기계어의 구성
기계어의 구성
기계어는 전류가흐르지않는 0과 전류가 흐르는 1로구성되어있다. 전기는 최대 흐르지않는다와 흐른다의 의미만 표현할수있기때문이다.
0과 1은 2진수라고 하는데 컴퓨터할떄 2진수를 사용하는것이 이이유이다.
허나 0과1로 표현하면 너무커지기 때문에 16진수로 나타내는경우가있다. 16진수로 나타내면 보기가 편해지기떄문이다. 따라서 16진수를 쓰는경우가 대부분이다.
기계어는 16진수로 표기를 하여도 보기가 힘들다. 따라서 인간이 보기편한 어셈블리어로 볼수가있는데 cpu에서 기계어를 쓰듯이 어셈블리어도 cpu에 바로쓸수있다. 기계어와 어셈블리어는 1:1대응한다.
어셈블리어는 크개두가지로 나눌수있다.
작동코드와 오퍼랜드로 나눌수있다.
작동코드에는 명령어가 들어가고 오퍼랜드에는 수행할 주소가있다.
작동코드는 jmp cmp mov sub 등 여러가지가있다. 작동코드 뒤에는 오퍼랜드가 들어가는데 연산을 할려면 2개 이상의 대상이필요하다 허나 어셈블리어에서는 1개또는 2개의 오퍼랜드만쓴다. 3개이상의 오퍼랜드는 쓰지않는다.
오퍼랜드를 알아보자 오퍼랜드는 16비트 32비트 64비트가 있는데 컴퓨터의 발전에 따라 늘어난다.
16비트에서는 ax,bx,cx,dx,si,di가 있는데 32비트에서는 e가붙어서 eax,ebx,ecx,edx,esi,edi로 비뀌었고 32비트에서 16비트 레지스터를 사용할수있고 64비트에서는 e가 r로 변경되어 rax,rbx,rcx,rdx,rsi,rdi로 쓸수있다.
역시 64비트에서도 32비트레스터와 16비트레지스터를 쓸수있다.
각 레지스터가 의미하는것은
EAX - 주로 변수,산술 계산을 하며 리턴값
EBX - 주로 변수,리턴값영도로는 사용하지 않음
EDX - 주된 용도가 없고 마이크로 프로세서에서 추가적인 레지스터 만들어놓것
ECX - 카운터 변수로 사용
ESI - 시작 인덱스
EDI - 목적지 인덱스
를 의미합니다.
이렇게 글로만 하는것보단 직접어셈블리 코딩을 해보는것이 좋을것이나 어셈블리코딩을 해보자
파일 asm.asm
section .data
db msg "hello hell"0x0A
section .text
golbal _start
_start
mov eax,4
mov ebx,1
mov ecx,msg
mov edx,12
int 0x80
mov eax,1
mov ebx,0
int 0x80
이렇게 코드를 작성한후에 저장을 한 후 nasm를 설치해주자
우분투에서는
sudo apt-get install nasm
데비안에서는
sudo yum install nasm
윈도우에서는 nasm홈페이지에 들어가서 윈도우용 nasm를 다운받는다. (홈페이지는 직접찾아주세용)
설치를 했으면 컴파일을 해야한다.
컴파일 하기전에 자신의 시스템이 32비트인지 64비트인지 알아야한다.
uname -p명령어로 알아본다
x86 이뜨면 32비트이고 x86_64가 뜨면 64비트이다.
윈도우에서는 제어판에가서 알아보자
32비트의경우
nasm -f elf asm.asm
64비트의경우
nasm -f elf64 asm.asm
으로 컴파일한후 공통적으로
ld asm.o
로 링크를 해준뒤 ./a.out 으로 링크한 프로그램을 실행한다.
실행해보면 hello hell 이라는 문자가 출력될것이다.
어셈블리어로 코딩을 한것이다.
이러면 section과 mov 그리고 int 0x80이 궁금할것인데
section .data 는 어셈블리에서 문자열이나 변수를 저장하는 구역이고
section .text 는 어셈블리어 코드가 들어가는 구역입니다.
mov는 앞오퍼랜드에 뒤의오퍼랜드를 대입한다는 것입니다.
int 0x80은 실행을 의미하는 작동코드와 오퍼랜드이고요
eax 에 write함수를 의미하는 시스템콜번호가 들어갓고요 ebx에는 정상적인 write함수의 출력번호이고 ecx에는 문자열이 edx에는 문자열 크기가 담겨있고요
기본적으로 알아두어야할 작동코드는
mov sub add cmp test jmp inc dec ret xor or rep and zf je pop push pushad popad 등이 있습니다. 다못쓰갯어요
mov 는 뒷오퍼랜드를 앞오퍼랜드에 대입시키는것이고
sub는 앞오퍼랜드에서 뒷어포랜드를 뺀다는것이고
add는 앞오퍼랜드에 뒷오퍼랜드를 더한다는것이고
cmp는 앞오퍼랜드에서 뒷오퍼랜드를 뺸값이 0이면zf를 1로 변환합니다.아닐경우에는 0으로 변환하고요
참고로 실제로 빼는것이아닌 가짜로 뺀값입니다. 레스트터의 값을 확인해보면 변하지 않습니다.!!!
je는 zf가 0이면 오퍼랜드로 jmp를 합니다.
cmp와 je는 같이 쓰이므로 기억해두시면 좋습니다.
jmp는 오퍼랜드 주소로 이동합니다.
test는 앞오퍼랜드와 뒷오퍼랜드를 and연산하여서 연산값이 0이면 zf를 0으러 변환하고 0이아니면 1로 변환한다.
test도 가짜로 and연산을 하여서 나타낸다 레지스터의 값은 변하지 않는다.
test또한 zf와 같이 쓰인다.
inc는 오퍼랜드값이서 1를 더한다
dec는 오퍼랜드 값에서 1를 뺸다.
ret은 호출된 함수에서 호출한 함수로 복귀하고
xor은 앞오퍼랜드와 뒤오퍼랜드값을 xor연산을 한다.
or도 앞오퍼랜드와 뒤오퍼랜드값을 or연산을 한다.
and 도 앞오퍼랜드와 뒤오퍼랜드값을 and연산을 한다.
rep 는 ecx레지스터를 카운터로 사용하여 0이될떄까지 오퍼랜드값으로 이동한다 반복문이되는셈이다,
이 외에도 이려가지 작업코드가 있으므로 알아보는것이 좋다.
push 오퍼랜드를 스택에 넣는다.
pop 스택에서 맨위값을 오퍼랜드에 대입시킨다.
PUSHAD : 모든 레지스터를 EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI 순서로스택에넣고
popad는 반대로 꺼냄니다.
번지 지정 방식은 프로그램이 수행되는 동안 사용될 데이터의 위치를 지정하는것이다. 따라서 효울적인 지정방식이 필요하다.
mod r/m 오퍼랜드가 레지스터 또는 메모리에 있는지를 나타낸다. mod, reg/opcode, r/m의 세개의 필드로 구성되어 있다.
SIB Byte ModR/M 필드에 의해 간접 어드레스 형태로 주소가 지정되어졌의면 베이스 어드레스나 스케일 인덱스와 같은 추가적인 어드레스 지정 형식을 구성하고자 할 대 그 정보가 들어간다 SS, Index, Base 의 세 가지 필드로 구성되어 있다
번지 지정 방식이란 프로세서가 취급할 정보가 위치하는 메모리 번지 또는 레지스터를 지정하는 방법을 말하는 것이며, 인텔의 경우 오퍼랜드가 레지스터 내에 위치할 경우에 사용한다.32비트, 16비트, 8비트 일반 레지스터 중 하나가 될수 있다.
주소 지정 : 실제 데이터 값을 구하려고 인스트럭션의 주소 부분의 값을 수정하거나 다른 것으로 대체하는것
주소 지정 이유 : 융통성 제공 및 주소부분(Operand)의 브트수 절약것것허나 컴퓨터 내에서 주소를 지정하는 방식에는 접근에 의한 방식과 계산에 의한 방식이 있음
접근 방식에 의한 주소 지정
즉시 주소 지정 연산자, 실제데이터
주소 필드에 있는 값이 실데 데이터가 되는 방식그래서 메모리 참조를 하지 않는다.
주기억장치의 참조가 없어서 가장 빠르나 오퍼랜드의 길이에 제약이 있어 모든 데이터를 표현할 수 없다
직접 주소 지정
주소 필드에 있는 값이 실제 데이터가 기억된 메모리 내의 주소가 되는 방식 메모리 참조를 한번 한다.
간접 주소 지정
주소 필드가 지정하는 곳에 있는 메모리의 값이 실제 데이터가 저장된 주소를 가지고 있는 방식이다.
적은 비트의 명령어로 넓은 기억 장소의 번지를 지정할 때 유용하다 메모리 참조는2회 이상힌다.
처리속도 : 즉시주소(빠르다) → 직접 주소 → 간접 주소(느리다)
명령어 길이 : 간접 주소(짧다) → 직접 주소 → 즉시 주소(길다)
계산에 의한 주소 지정: 실제 데이터가 들어갈 메모리의 위치를 지정할 때 명령어의 주소 부분에 있는 값과 특정 레지스터에 기억된 값을 더해서 지정하는 방식
상대 주소지정: 프로그램 카운터와 주소 부분이 더해져서 유효 주소 결정. 특정 레지스터가 PC(프로그램 카운터)인 경우
인덱스 주소지정: 인덱스 레지스터값과 주소부분이 더해져서 유효 주소 결정. 특정 레지스터가 인덱스 레지스터인 경우
베이스 레지스터 - 베이스 주소를 이용
인덱스 레지스터 - 인덱스 레지스터를 이용
상대주소 - 프로그램 카운터(PC)를 이용
프로그램 카운터 : 다음에 실행될 명령어를 메모리 주소를 기억한다.
'스터디 > Windows 구조와 원리 OS를 관통하는 프로그래밍의 원리' 카테고리의 다른 글
실행 압축) 실행압축과 일반압축 (비 손실압축과 손실 압축) (0) | 2014.09.06 |
---|---|
데이터의 표현과 메모리 구조 (0) | 2014.07.15 |
컴퓨터의 구조와 역사 (0) | 2014.07.15 |
목차 및 책 구성 (0) | 2014.07.15 |
스터디 카테고리에 관한 설명 (0) | 2014.07.15 |