Assembly 기초
Intel 문법에 기반
1. 범용 레지스터(Operand)
레지스터는 CPU가 요청을 처리하는데 필요한 데이터를 일시적으로 저장하는 다목적 공간이다. 레지스터를 사용하면 고속으로 데이터 처리 가능
- AX : 누산기 레지스터라고 불리며, 더하기 빼기 등의 산술논리연산에 사용, 함수의 리턴값 저장(가장 많이 쓰이는 레지스터)
- BX : 베이스 레지스터라고 불리며, EAX와 같이 연산에 자주 사용되지만 리턴값은 저장되지 않음(메모리 주소 지정시에 주로 사용, 배열의 인덱스값 저장)
- CX : 계수기(카운터) 레지스터라고 불리며, for문에서 ++연산과 같이 카운트하는데 사용
- DX : 데이터 레지스터라고 불리며, AX와 함께 확장된 레지스터로 사용(곱셈, 나눗셈에서 EAX와 같이 쓰임)
- SI : 소스 인덱스라고 불리며, 데이터를 옮기거나 복사할때 소스의 주소가 복사(인덱스 레지스터)
- DI : 데스티네이션 인덱스라고 불리며, 데이터를 옮기거나 복사할때 목적지의 주소가 복사(인덱스 레지스터)
- BP : 스택의 베이스 포인터로 스택의 바닥을 가르키는 레지스터. 스택에 값이 쌓이면 ESP도 증가(포인터 레지스터)
- SP : 스택의 탑 포인터로 스택의 가장 윗부분을 가르키는 레지스터. 밑에는 Return값이 있다(포인터 레지스터)
Operand에 사용되는 레지스터들이며 앞에 R이 붙으면 64bit, E가 붙으면 32bit, 아무것도 붙지 않으면 16bit
Bit, Byte(8Bit), Word(16Bit), DWord(32bit) 레지스터는 32bit인데 00 00 00 00 이런식으로 Byte(8Bit)를 두 칸으로 사용.
* 레지스터에 [](대괄호)가 씌워져있다면 주소를 가르킴
* EIP : CPU가 다음에 실행할 명령어 주소를 가르킴
* EntryPoint : 운영체제에서 프로그램으로 이동하는 것을 말함, 프로세서는 프로그램이나 코드에 진입해서 실행을 시작
2. 플래그 레지스터(EFlag)
컴퓨터가 어떠한 연산을 수행하고 난 후 그 결과를 기록하는 역할
- ZF : 산술이나 비교 연산의 결과를 나타냄(0 = 결과가 0이 아님, 1 = 결과가 0) (zero)
- CF : 산술 연산 후 상위(가장 왼쪽) 비트의 캐리를 포함. 또한 비트 자리이동(shift) 혹은 비트 회전(rotate)연산 후 가장 마지막의 비트 내용을 포함(carry)
- OF : 산술 연산 후 상위(가장 왼쪽)비트의 오버플로를 나타냄.(overflow)
- SF : 산술 연산의 결과 값에 대한 부호를 포함함.(0 = 양수, 1 = 음수) (sign)
- PF : 연산 결과 1비트들의 개수를 나타낸다. 개수가 짝수인경우 even parity, 홀수인경우 odd parity라고 부름(parity)
- AF : 특수화된 산술에서 사용되며, 산술 연산에서 비트 3에서 비트 4로의 캐리를 포함함(auxiliary carry)
- DF : 문자(string)데이터를 이동시키거나 비교할 때 왼쪽 또는 오른쪽의 방향을 결정(direction)
- IF : 키보드 입력과 같은 외부 인터럽트가 처리되어야 하는지 또는 무시되어야 하는지 나타냄(interrupt)
- TF : 단일 단계 모드(single-step mode)의 프로세서 연산을 허용. DEBUG와 같은 디버거 프로그램은 TF플래그를 설정해서, 한번에 하나씩 명령어를 실행시키고, 레지스터와 메모리 상에서 그 영향을 조사할 수 있게 한다(trap)
3. 명령어(Opcode)
- nop : 아무것도 행동하지 않음
- mov : 메모리나 레지스터의 값을 옮길 때 사용
- lea : 주소를 옮길때 사용
- push : 값을 스택 가장 상위에 있는 값(ESP) 저장(스택의 가장 윗부분을 가르키는 ESP도 워드 크기만큼 증가)
- pop : 스택 가장 상위에 있는 값(ESP) 불러옴(스택의 top에서 하나의 워드를 목적지에 불러옴, ESP도 워드 크기만큼 감소)
- inc : ++연산자와 동일하게 값을 1증가
- dec : --연산자와 동일하게 값을 1감소
- add : 앞의 레지스터에 더함
- sub : 앞의 레지스터에 뺌
- call : 함수 호출
- ret : call로 호출된 함수를 종료하고 함수 다음 줄로 이동
- int : OS에 할당된 인터럽트 영역을 system call
* int : 인터럽트를 일으키는 명령어 입니다. 뒤의 오퍼랜드로 어떤 숫자가 나오느냐에 따라 각기 다른 처리가 일어남. 현재 32비트 시대에서는 애플리케이션 레벨에서의 인터럽트는 한계가 있고, ring0 레벨로 내려가기 전까진 거의 사용할 일이 없는 명령어가 됨. 리버스 엔지니어링을 하다보면 INT 3 명령어로 옵코드가 0xCC인 DebugBreak()를 가장 많이 만남.
* 인터럽트 : 운영체제에서 컴퓨터에 예기치 않은 일이 발생하더라도 작동이 중단되지 않고 계속적으로 업무 처리를 할 수 있도록 해주는 기능
*비교구문 명령어
- cmp : 두 레지스터의 값을 비교구문
- test : 호출된 함수들이 보통 EAX에 리턴된다는 것을 이용한 비교구문. 결과값을 저장하지 않음
cmp 명령어는 주어지는 두 값을 뺄셈을 하여 처리하고, test 명령어는 주어지는 두 값을 논리적 AND 연산해서 처리하는 점이 다르며, 두 명령어가 조건 분기문을 결정하기 위해서 사용된다는 점은 같다.
cmp가 영향을 미치는 플래그들은 ZF, OF, SF, CF이고 만약 ZF 플래그가 ZF=1로 세팅되었다면 주어진 두 값이 같았다는 것을 의미. 그 외에 같지 않았을 경우에는 OF, SF, CF를 이용해서 어느 쪽이 더 큰지를 알 수 있음.
test가 영향을 미치는 플래그는 SF, ZF, PF이고, test 명령어는 같은 피연산자를 가지게 되는데 그러므로 중요한것은 피연산자가 0이냐, 0이 아니냐하는 것이다. 0이면 ZF가 1로 세트되고, 0이 아니면 ZF가 0으로 세트됨.
*jmp관련 명령어(cmp나 test의 명령어의 결과에 따라 점프하는 명령어)
- jmp : 특정한 곳으로 분기
short점프는 -127 ~ 127 byte범위 안에서, near점프는 같은 세그먼트 내부에서, far점프는 현재 세그먼트를 벗어날 때 사용된다. JMP 명령어는 되돌아올 리턴 어드레스 값을 저장하지 않는다.
Unsigned 계열
- je, jne : 비교결과가 같을때, 같지 않을때 점프(jump equal, jump not equal)
- jz, jnz : 결과가 0일때, 0이 아닐때 점프 = je, jne(cmp명령에서 결과가 같으면 0출력) (jump zero, jump not zero)
- ja, jna : cmp A, B에서 A가 클때, 크지 않을때 점프(jump above, jump not above)
- jae, jnae : 크거나 같을때, 크거나 같지 않을때(작을때) 점프(jump above equal, jump not above equal)
- jb, jnb : cmp A, B에서 A가 작을때, 작지 않을때 점프(jump below, jump not below)
- jbe, jnbe : 작거나 같을때, 작거나 같지 않을때(클때) 점프(jump below equal, jump not below equal)
- jc, jnc : c플래그가 1일때, 0일때 점프(jump carry, jump not carry)
- jnp, jpo : p플래그가 0일때, 홀수일때 점프(jump not parity, jump parity odd)
- jp, jpe : p플래그가 1일때, 짝수일때 점프(jump parity, jump parity even)
- jecxz : ecx레지스터가 0일때 점프(jump ecx zero)
Signed 계열
- jg, jng : cmp A, B에서 A가 클때, 크지 않을때 점프(jump greater, jump not greater)
- jge, jnge : 크거나 같을때, 크거나 같지 않을때(작을때) 점프(jump greater equal, jump not greater equal)
- jl, jnl : cmp A, B에서 A가 작을때, 작지 않을때 점프(jump less, jump not less)
- jle, jnle : 작거나 같을때, 작거나 같지 않을때(클때) 점프(jump less equal, jump not less equal)
- jo, jno : o플래그가 1일때, 0일때 점프(jump overflow, jump not overflow)
- js, jns : s플래그가 1일때, 0일때 점프(jump sign, jump not sign)
-조건 점프 명령을 조합하여 if(a > b), for, while 등의 조건문 구현
참조 사이트
https://aistories.tistory.com/12
어셈블리어(Assembly) 기초
어셈블리어(Assembly) 입문자를 위한 어셈블리어 기초 ## 목차 ## 0x01. 어셈블리 언어란? & 배우는 목적 0x02. 어셈블리 언어를 위한 기본 지식 0x03. 어셈블리 명령어의 구성 0x04. 주소지정방식의 이해
aistories.tistory.com
[어셈블리] 범용 레지스터, 세그먼트 레지스터, 포인터 레지스터, 인덱스 레지스터, 플래그 레지�
1. 범용 레지스터 - 범용 레지스터(general-purpose registers)에는 32비트 E(extened)AX, EBX, ECX, EDX 등이 있다. 이러한 레지스터들의 오른쪽 16비트 부분을 각각 AX, BX, CX, DX라 부른다. 예를 들어 AX는..
karfn84.tistory.com
레지스터 (Register)
운영 모드에 대해서 알아봤으니 이제 그에 따른 사용되는 레지스터에 대해 알아보자.레지스터에 대해선 한...
blog.naver.com
https://blog.naver.com/aaasssddd25/220901909436
[정리] 어셈블리어 정리
안녕하세요. 칸입니다. 개인 사정으로 인하여 글을 너무 늦게 올리게 되었습니다.시험 마치고 바로...
blog.naver.com
상황별 기초 어셈블리어
어셈블리 명령어를 상황별로 어떻게 사용되는지 정리해보며 공부해보자. 1. 데이터 이동 : 어셈블리에서 데이터를 옮기고자 할때는 MOV 명령어를 사용한다. MOV [복사될 곳], [읽어들일 곳] MOV EAX, E
dakuo.tistory.com