mov 명령어
==================================Outline====================================
mov 명령어
----------------------------------------------------------------------------
mov 명령어
mov 명령어에 대하여 공부해보자.
mov 명령어의 문법은 mov destination, source이다.
메모리에 있는 변수끼리의 mov 명령어는 실행 불가능하다.
ex) mov Count, Number //illegal for two memory operands
CPU 레지스터를 거쳐서 데이터가 이동해야 한다.
Opcode는 cpu가 이해할 수 있는 언어이기 때문에 exe파일 자체를 assembly language로 고칠 수 있다.
AL에 100을 넣는 assembly를 작성해보자.
mov AL, 64h //assembly language
B0 64 //기계어
C는 8, 10, 16진수만 사용 가능하지만 assembly는 2진수도 가능하다.
어셈블러를 기계어로 변환시켜보자.
mov CH, 10
-> B5 0A
mov EDX, 64
-> BA 40 00 00 00 //little endian
direct는 메모리에 직접 집어넣기 때문에 메모리 주소가 필요하다.
변수가 아닌 주소를 사용하기 때문에 주소 값 4byte가 필요하다. 값을 이동시키기 위해서는 원본과 복사본이 필요한데 두 개의 크기는 같아야 한다. 때문에 원본과 복사본의 용량이 각 각 4byte로써 8byte. opcode가 1byte를 사용한다.
immediate(상수) 값은 cpu에 있다.
register indirect
mov EDX, 64 //EDX에 64를 넣는다.
mov [EDX], 64 //EDX가 가리키는 주소에 64를 넣는다. 포인터와 같은 기능
아래 표에서 C7은 2개이기 때문에 이를 구별하기 위한 1byte가 필요하다.
AL, AX, EAX에 데이터를 복사하는 기계어는 따로 분리되어 있다. accumulate는 가장 많이 사용하는 명령어이기 때문이다.
mov AL, 100 //A0
mov BL, 100 //8A
mov CL, 100 //8A
mov BH, 100 //8A
//segment register들은 사용하지 않는다.
//굳이 op코드를 외울 필요 없이 표를 보는 방법을 습득해야 한다.
xchg eax, ebx ; eax와 ebx값을 바꾼다.
레지스터에 데이터 값은 빅엔디안, 메모리의 값은 리틀 엔디안으로 저장되어 있다.
AL, AH는 따로 지원하지 않고 EAX부터 따로 opcode가 나뉜다.
mov와 xchg를 사용할 때의 클럭 수의 차이를 살펴보자.
mov AL, AH ;1 clock
mov AH, BH ;1 clock
mov BH, AL ;1 clock
xchg AH, BH ;3 clock
어셈블리어 코드는 작성자가 용량과 효율을 고려하여 코드를 작성하여야 한다.
컴파일러는 assembly 언어를 기계어로 바꿀 때 용량과 효율을 고려하여 컴파일 한다.
컴파일러보다 assembly 언어를 최적화 시킬 수 없다면 assembly어는 손대지 않는 것이 낫다.
정수의 덧셈/뺄셈 명령어
덧셈 : add dest., source
뺄셈 : sub dest., source
결과는 dest.에 저장된다.
연산을 하는 명령어는 다른 레지스터에 영향을 미친다.
EFL(Extended Flag) 은 비트들의 플래그만 모아 놓은 레지스터이다.
//책에 틀린 내용이 존재함으로 위의 연산을 일일이 확인해 보아야 한다.
Windbg를 사용하여 EFL의 값을 확인할 수 있다.
표에 나와 있는 내용을
00 00 02 06
-> 0(SF)0(ZF)10 0110(CF)
계산 결과가 부호비트를 넘었을 때도 overflow가 발생한다.