출처 : http://zerohz.tistory.com/61
출처 : http://maj3sty.tistory.com/717
[어셈블리어]
Push : sp 레지스터를 조작하는 명령어중의 하나이다. 스택에 데이터를 저장하는데 쓰인다.
ex:) Push eax : 스택에 Eax의 값을 스택에 저장한다.
ex:) Push 20 : 즉석값인 20을 스택에 저장한다.
ex:) Push 401F47 : 메모리 오프셋 401F47의 값을 스택에 저장한다.
Pop : 이또한 sp 레지스터를 조작하는 명령어중 하나이다. 스택에서 데이터를 꺼내는데 쓰인다.
ex:) Pop eax : 스택에 가장 상위에 있는 값을 꺼내애서 eax에 저장한다.
* 주의점 : Push 의 역순으로 값은 스택에서 Pop 된다.
Mov : 메모리나 레지스터의 값을 옮길 때[로 만들 때]쓰인다.
ex:) Mov eax,ebx : ebx 레지스터의 값을 eax로 옮긴다[로 만든다].
ex:) Mov eax,20 : 즉석값인 20을 eax레지스터 에 옮긴다[로 만든다].
ex:) Mov eax,dword ptr[401F47] : 메모리 오프셋 401F47 의 값을 eax에 옮긴다[로 만든다]
Lea : 오퍼렌드1의 값을 오퍼렌드2의 값으로 만들어준다.
ex:) Lea eax,ebx : eax레지스터의 값을 ebx의 값으로 만든다.
Inc : 레지스터의 값을 1증가 시킨다.
ex:) Inc eax : Eax 레지스터의 값을 1증가 시킨다.
Dec : 레지스터의 값을 1 감소 시킨다.
ex:) Dec eax : Eax 레지스터의 값을 1 감소 시킨다.
Add : 레지스터나 메모리의 값을 덧셈할떄 쓰임.
ex:) Add eax,ebx :Eax 레지스터의 값에 ebx 값을 더한다.
ex:) Add eax,50 :Eax 레지스터에 즉석값인 50을 더한다.
ex:) Add eax,dword ptr[401F47] : Eax 레지스터에 메모리 오프셋 401F47의 값을 더한다.
Sub : 레지스터나 메모리의 값을 뻇셈할떄 쓰임.
ex:) Sub eax,ebx : Eax 레지스터에서 ebx 레지스터의 값을 뺸다.
ex:) Sub eax,50
Eax : 레지스터에서 즉석값 50을 뺸다.
ex:) Sub eax,dword ptr[401F47] : Eax 레지스터에서 메모리 오프셋 401F47의 값을 뺸다.
Nop : 아무동작도 하지 않는다. : 90
Call : 프로시저를 호출할떄 쓰인다.
ex:) Call dword ptr[401F47] : 메모리 오프셋 401F47을 콜한다.
DIV <Target> - Division. EAX를 <Target>으로 나누는 연산이다. 결과로 몫은EAX에 나머지는 ECX에 들어간다.
ex :) MOV EAX, 64h
MOV ECX, 9h
DIV ECX ; 64h(100) / 9h(9) = 몫 : 0Bh(11) , 나머지 1h이므로
EAX = 0Bh, ECX = 1h가 저장된다.
IDIV <Target> - Integer Division. DIV와 똑같다. 하지만 다른점은 부호있는 정수를 다룬다는 점이다.
MUL <Target> - Multiplication. EAX와 <Target>을 곱하여 EAX에 저장한다.
ex:) : MOV EAX, 2h
MUL 4h ; EAX에는 2h * 4h = 8h가 저장된다.
IMUL <Value> - Integer Multiplication. EAX와 <Value>를 곱하여 EAX에 저장한다.
IMUL <Destination>, <Value> - <Destination>과 <Value>를 곱하여 <Destination>에 저장한다.
IMUL <Destination>, <Value>, <Value> - 2개의 <Value>를 곱한 후에 <Destination>에 저장한다.
TEST <Target1>, <Target2> - 이 연산은 대부분이 <Target1>과 <Target2>가 같게 설정된다. 예를들면 TEST EAX, EAX. 이 연산은 논리회로의 AND연산을 수행하지만 결과값을 저장하지 않는다. 단지 EAX=0일경우 ZF=1이 되고 EAX!=0일경우 ZF=0이 된다. 그리고 OF, CF는 0이된다.
ex :) TEST EAX, EAX
LODS, LODSB, LODSW, LODSD(Load String Byte, Word, DWord) - ESI가 가르키는 곳에서 지정한 크기(Byte, Word, DWord) 만큼 읽어와 EAX에 복사한다. ESI는 복사한만큼 이동한다.
STOS, STOSB, STOSW, STOSD(Store String Byte, Word, DWord) - EAX에 들어이있는 데이터를 지정한 크기만큼 EDI가 가르키는 주소에 복사한다. EDI는 복사된 만큼 이동한다.
CLD(Clear Direction flag), STD(Set Direction flag) - Direction Flag를 Set하거나 Clear할때 사용한다.
CMC(Complement Carry flag), CLC(Clear Carry flag), STC(Set Carry flag) - Carry flag를 순서대로 반전, Clear, Set시킨다.
SHL <Destination>, <Value> - Shift Logical Left. <Destination>에 <Value>만큼 Shift연산을 왼쪽으로 수행한다. 만약 <Destination>보다 커질경우 CF=1이 된다.
SHR <Destination>, <Value> - Shift Logical Right. SHL과 기능은 동일하며 Shift연산이 오른쪽으로 진행된다.
ROL <Destination>, <Value> - Rotate Left. SHL과 기능은 동일하다. 단지 자리수가 늘어날경우 해당 비트가 오른쪽 끝으로 이동한다.
Ret : 콜한 지점으로 돌아간다.
Cmp : 레지스터와 레지스터혹은 레지스터 값을 비교하기위하여 쓰인다.
ex:) Cmp eax,ebx : Eax 레지스터와 Ebx 레지스터의 값을 비교한다.
ex:) Cmp eax,50 : Eax 레지스터와 즉석값 50을 비교한다.
ex:) Cmp eax,dword ptr[401F47] : Eax 레지스터와 메모리 오프셋 401F47의 값을 비교한다.
Jmp : 특정한 메모리 오프셋으로 이동할떄 쓰인다.
ex:) Jmp dword ptr[401F47] : 메모리 오프셋 401F47 로 점프한다.
조건부 점프: Cmp나 Test 같은 명령어의 결과에 따라점프한다.
Je : Cmp나 Test 의 결과가 같다면 점프
Jne : Cmp나 Text 의 결과가 같지 않다면 점프
Jz : 왼쪽 인자의 값이 0 이라면 점프
Jnz : 왼쪽 인자의 값이 0 이 아니라면 점프
Jl : 왼쪽 인자의 값이 오른쪽 인자의 값보다 작으면 점프(부호있는)
Jnl : 왼쪽 인자의 값이 오른쪽 인자의 값보다 작지 않으면(크거나 같으면) 점프 (부호있는)
Jb : 왼쪽 인자의 값이 오른쪽 인자의 값보다 작으면 점프(부호없는)
Jnb : 왼쪽 인자의 값이 오른쪽 인자의 값보다 작지 않으면(크거나 같으면) 점프 (부호없는)
Jg : 왼쪽 인자의 값이 오른쪽 인자의 값보다 크면 점프
Jng : 왼쪽 인자의 값이 오른쪽 인자의 값보다 크지 않으면 (작거나 같으면) 점프
Jle : 왼쪽 인자의 값이 오른쪽 인자의 값보다 작거나 같으면점프 (부호있는)
Jge : 왼쪽 인자의 값이 오른쪽 인자의 값보다 크거나 같으면 점프
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
약 이정도의 명령어들이 가장 많이 나오는 것들임으로
최소한 위에 나온것들은 외워 두도록 하자.
이글에서는 5가지 논리연산에 대해서 쓸것이다.
논리연산자는 두 오퍼렌드의 값의 비트들을 대응시켜 명령에 따른 적절한 값을 구하여 첫번쨰 오퍼렌드의 값을 바꾸어 주는것이다.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
AND 연산 : 대응되는 비트가 둘다 1이면 결과는 1이고 그외의 결과들은 모두 0 이 된다.
- AND EAX,10 : 이를 계산하기 위해 우선 두 오퍼렌드의 값을 2진수로 바꾸어 주면 8은 1000 이 되고 10은 1010 이 되고 AND 연산은 둘다 1이여야 1이 됨으로 결과는 1000 이 됩니다.
OR 연산 : 대응되는 비트중 하나가 1 또는 둘다 1이면 결과는 1이고 그외는 모두 0이 된다.
- OR EAX,10 : 이를 계산하기 위해 두 오퍼렌드의 값을 2진수로 바꾸어 주면 8은 1000이 되고 10은 1010이 되고 OR 연산은 한쪽 또는 양쪽둘다 1이면 1이고그외는 모두 0 임으로 결과는 1010이 된다.
XOR 연산 : 대응되는 비트 중에서 한비트가 1이고 다른 비트가 0이면 1이 되고 두개의 비트가 1이면 0 이 되고 두개다 0 이어도 0이 된다.
XOR EAX,10 : 이를 계산하기 위해 두 오퍼렌드의 값을 2진수로 바꾸어 주면 8은 1000이 되고 10은 1010이 되고 XOR 연산은 한쪽만 1이어야 1임으로 결과는 10이 된다.
NOT 연산 : NOT 연산은 오퍼렌드의 값을 반대로 하여 준다.
NOT EAX : 이를 계산하기 위해 오퍼렌드의 값을 2진수로 바꾸어 주면 10은 1010이 되고 NOT 연산은 1 과 0을 반대로 하여 줌으로 결과는 0101 이 된다.
* 참고 : Test 연산은 오퍼렌드에 영향을 주지 않으며 플래그만 세트 시키어 준다
[레지스터]
1. 범용 레지스터
- EAX 레지스터 : 누산기인 EAX 레지스터는 입출력과 거의 모든 산술연산에 사용된다. 곱셋과 나눗셈, 변환 명령어등은 반드시 EAX 레지스터를 필요하게 된다.
EAX 레지스터는 32bit의 레지스터이고 16bit 의 레지스터로 AX가 있다. (AX는 왼쪽의 AH와 오른쪽의 AL로 이루어져 있다)
- EBX 레지스터 : EBX는 주소지정을 확대하기 위한 인덱스로서 사용될수 있는 유일한 범용 레지스터 이며, 다른 일반적인 계산 용도로도 쓰인다.
EBX는 32bit 레지스터이고 16bit로 EB가 있다. (EB는 왼쪽의 BH와 오른쪽의 BL로 이루어져 있다)
- ECX 레지스터 : ECX는 루프의 반복 횟수나 좌우방향의 시프트 비트 수를 기억한다. 그외의 계산에도 사용된다.
ECX는 32bit 레지스터이고 16bit로 CX가 있다. (CX는 왼쪽의 CH와 오른쪽의 CL로 이루어져 있다.)
- EDX 레지스터 : EDX는 몇몇 입출력 동작에서 사용 된다.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2. 플래그 레지스터
- OF [Over Flow] : 산술연산후 상위 비트의 오버플로를 나타냄
- DF [Direction] : 스트링 데이터를 이동하거나 비교할떄 왼쪽 또는 오른쪽으로의 방향을 결정한다.
- SF [Sign] : 산술결과의 부호를 나타낸다[0=양수,1=음수]
- ZF [zero] : 산술연산 또는 비교동작의 결과를 나타낸다[0=결과가 0이 아님,1=결과가 0임]
- CF [Carry] : 산술연산후 상위 비트로부터의 캐리 그리고 시프트 또는 회전동작의 결과 마지막 비트 내용을 저장한다.
- TF [trap] : 프로세서가 단일 스텝 모드(single-step mode)를 동작할수 있도록 해준다.
[참고]
1. 나눗셈 연산의 피젯수는(32bit의 나눗셈을 가정) 항상 edx:eax 이다.
2. cdq 는 나눗셈을 위해 피젯수의 사이즈를 확장하는 것이다.
나눗셈연산(div, idiv)은 eax와 edx에 의해서만 이루어집니다
- 피젯수(나눔을 당하는 수) 는 eax, edx에만 들어갈 수 있다는 얘기에요
16 / 5 연산을 한다고 가정해 봅시다.
16과 5 둘다 32bit data라고 가정하구요
그럼 일단 eax에 16을 넣습니다. 그 다음 ebx(다른레지스터나 메모리도 상관없음)에
5를 넣습니다. 그 다음 div 연산을 하면.........될것 같지만 안됩니다..
일반적으로 제수(여기서는 5)가 32bit이면 피젯수(여기서는 16) 는 64bit가 되어야
32bit 값을 가지는 몫을 얻을 수 있습니다.
그래서 피젯수의 bit를 확장 시켜주는것이 바로 cdq 연산입니다
32bit 크기의 eax의 값을 64bit의 값인 edx:eax로 만들어줍니다.
여기서 edx는 상위자리가되고 eax는 하위 자리가 되죠
자..그럼 cdq 연산까지 끝났으면 edx:eax에 16이 들어가있고 ebx에 5가 들어있겠네요
그럼 idiv연산을 해봅시다(div는 부호가없는 나눗셈 idiv 부호가 있는 나눗셈)
그럼 몫과 나머지가 나와야 하겠죠? 그 결과는 다시 eax와 edx로 들어가는데
eax에는 몫이, edx에는 나머지 부분이 들어갑니다~
LoadLibrary GetProcAddress (로드 라이브러리 겟프락어드레스) 후에 변하지 않는 레지스터는
EBX EBP ESI EDI 이다. EAX, ECX, EDX 가 변한다WRITTEN BY
- RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.