[스무디]어셈블리어 강의 13~17강 정리
13. 메모리 지정 방식
-offset 이용하는 방법
ex) [eax+4]
*offset: 변위차
mov ebx, 402000
mov byte ptr [ebx], 0
mov byte ptr [ebx+2], 1
mov byte ptr [ebx+3], 2
mov byte ptr [ebx+4], 3
결과
[402000]: 00 01 02 03 ...
mov ecx, 0
mov byte ptr [402000 + ecx], cl
-> [402000] : 00 00 00 00
inc ecx
mov byte ptr [402000 + ecx], ecx
-> [402000] : 00 01 00 00
inc ecx
mov byte ptr [402000 + ecx], ecx
-> [402000] : 00 01 02 00
-index 지정 방식
mov ecx, 0
mov byte ptr [402000 + ecx*4], cl
-> 402000 : 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00
inc ecx
mov byte ptr [402000 + ecx*4], ecx
-> 402000 : 00 00 00 00 | 01 00 00 00 | 00 00 00 00 | 00 00 00 00
inc ecx
mov byte ptr [402000 + ecx*4], ecx
-> 402000 : 00 00 00 00 | 01 00 00 00 | 02 00 00 00 | 00 00 00 00
**규칙**
[base 주소 + offset + index * scale]
레지스터는 최대 2개 사용 가능
-> base로는 레지스터가 올 수 없음
index로는 반드시 레지스터를 사용해야 함
scale은 주로 자료형의 크기 (int: 4byte)
14~15. 조건분기 명령어
-점프는 종류가 여러개 있음, 인자는 하나
> 무조건분기: JMP [주소]
> 조건분기: 상태레지스터에 따라 다름
-상태 레지스터(비트)
Z (ero) | 제로 플래그 | 연산 결과가 0일 경우 |
C(arry) | 캐리 플래그 | 부호 없는 숫자의 연산 결과가 비트 범위를 넘어섰을 경우, 캐리가 발생한 경우 |
O(verflow) | 오버플로우 플래그 | 부호 있는 숫자의 연산 결과가 비트 범위를 넘어섰을 경우 |
S(ign) | 사인 플래그 | 연산 결과가 음수일 때, 연산 결과의 최상위 비트인 부호 비트가 담김 |
이번 강의에서 나온 상태 레지스터들을 정리해보았다.
조건 분기 명령어
-JZ: 제로플래그가 1이면 분기
ex)
eax를 1 감소시키면 0이 되므로 z=1로 바뀐다. 그 다음 eip에 분기 주소가 담기고 점프한다.
*mov eax, 0 한다고 z 플래그가 0으로 바뀌는건 아님
*je와 기계어가 같아서 올리디버거에서 명령어를 입력하면 자동으로 바뀐다.
-JE(Eqaul): 비교 결과가 같으면 점프
*cmp: 비교 연산자, 내부적으로 빼기를 수행해서 비교, 빼기를 한 결과를 저장하지 않고 버림
ex)
mov eax, 0
cmp eax, 0
cmp eax, 1
따라서 ZE와 JE가 같은 역할을 함, 기계어로 같음, 비교 결과가 같으면 z flag가 0이 되기 때문
-JNE(Not Equal) / JNZ(Not Zero): 제로 플래그가 0이면 분기, 둘이 기계어로 같음
-JA(Above): 부호가 없는 데이터 비교 결과 앞에 연산자가 크면 점프
Carry=0, Zero=0일 때
*JNBE = JA
-JB(Below) : 부호가 없는 데이터 비교 결과 앞에 연산자가 작으면 점프
Carry=1이면 점프(Zero는 상관 없음)
mov eax, 0
cmp eax, 1 c 1
-JNA(Not Above) / JNB(Not Below)
*각 JBE / JAE와 같음 (기계어가 같음), 등호 조건 포함
JNA(JBE): z=1 or c=1 이면 점프
JNB(JAE): z=0, c=0 or z =1, c=0이면 점프
-JC(Carry): carry 플래그가 세팅되어 있을 때
17강 조건분기 명령어 JG JL 상태레지스터 SF OF
-JG와 JL은 JA, JB와 다르게 부호가 있는 데이터로 비교
*오버플로우 비트
0 1 1 1 + 0 0 0 1 = 1 0 0 0
부호비트(sign bit)가 1이 되었음
부호가 있는 비트로 읽으면 -8이 되어버림, 이런 경우 오버플로우 비트 세팅
-JG(Greater): 부호가 있는 데이터를 비교해서 앞에 데이터가 크면 분기
Z=0, S=O면 점프
부호가 있는 데이터인지 없는 데이터인지는 명령어가 결정하는 것임
-JL(Less):
S<> O인 경우 점프
->연산 결과가 음수인 경우 오버플로우가 일어나지 않았을 때