Programming Tools/Assembly_어셈블리

어셈블리어 정리노트 3 - JMP, INC, DEC, ADD, SUB

LiDARian 2021. 5. 19. 23:12
반응형

JMP 명령어

명령어가 있는 메모리로 이동하게 해주는 jmp

JMP (SHORT) 00401005 // 00401005 메모리로 이동한다.

EIP는 실행할 곳의 주소를 담는 레지스터이다. EIP에 들어있는 주소로 이동해서, 해당 메모리 주소에 있는 명령어를 RAM에서 가져온다. 그러고 나서 그 명령어를 실행한다. 그리고 EIP는 읽어온 주소값의 크기만큼 증가한다.

JMP의 경우, MOV EIP 00401005가 들어간다고 생각하면 됨
단 EIP는 범용 레지스터가 아니므로 MOV가 아니라 JMP를 이용하는 것이다.


00401000 - MOV EAX, 0
00401005 - MOV EBX, 0
0040100A - MOV ECX, 0
0040100F - JMP (SHORT) 00401005

의 각각의 기계어는

B0 00000000
B8 00000000
B9 00000000
EB F4

EB F4에서 EB는 JMP SHORT, F4는 다음 명령어 위치와 JMP 목적지까지의 차이(-0x0C)를 의미한다.
EIP는 0040100F에서의 명령어를 실행한 이후, 00401011 00401005 순서로 이동하게 된다,


JMP SHORT 00401005에서 SHORT는 한 바이트 이내로 점프 거리를 기계어로 표현 가능할 때 사용한다.
아닌 경우는 long을 사용(혹은 아예 생략됨). 똑같이 목적지까지의 차이가 계산된다

JMP EAX도 가능하다. EAX에 들어있는 값으로 이동한다.
다만 JMP AX는… 가능은 하지만 보통 이정도 자리수면 운영체제에 할당되어있어서 접근이 안된다.

JMP DWORD PTR [00402000] 은 00402000번 메모리에 들어있는 값을 주소로 보고, 그 곳으로 이동한다는 의미이다.

증감 연산자 INC, DEC

INC (REG)(MEM)
DEC (REG)(MEM)

1씩 증감하는 연산자이다.

INC EAX // 40
INC AX // 66:40

오른쪽 주석은 기계어로 바꾸었을 때의 명령어이다. 16진수로 작성했다.

4바이트 레지스터 접근은 기계어가 1바이트만 사용된다.
4바이트 아닌 레지스터 접근은 기계어가 2바이트 사용된다.
즉 32비트 프로세서기준으론, 4바이트 레지스터 접근이 더 공간적으로 효율적이다.

이것은 메모리도 마찬가지다.

inc dword ptr [402000] 4바이트
inc word ptr [402000] 2바이트 사용
inc byte ptr [402000]  1바이트 사용

메모리에 대해서도 4바이트 접근이 더 효율적인 기계어가 나온다.

더하기 빼기 ADD, SUB

ADD (REG/MEM/DATA), (REG/MEM/DATA)
SUB (REG/MEM/DATA), (REG/MEM/DATA)

메모리끼리는 ADD, SUB 연산이 안된다.

인텔 문법 기준으로, 앞 부분에 뒷값을 더하거나 뺀다. 서로 다른 크기면 오류가 난다. 자료 크기를 변환하는 기계어는 없으니까..
ex) add eax, cx 는 오류다.

AT&T 문법의 경우, ADD나 SUB명령이

ADD (REPOSIT), (REG/MEM/DATA), (REG/MEM/DATA)
SUB (REPOSIT), (REG/MEM/DATA), (REG/MEM/DATA)

이런 형태이다.

메모리에서 ADD를 쓰는 경우,

MOV DWORD PTR [402000], 0
ADD DWORD PTR [402000], 2

DWORD를 안하면 0에 대한 사이즈 지정이 안된 것이라서 오류가 나타난다.


Tips

가끔 보이는 DB 00은 DATABYTE 00으로, 그냥 16진수 데이터를 의미한다.

반응형