[System] 어셈블리어 구조 & 주소

 

시스템 해킹


(1) 어셈블리어의 구조

  • 어셈블리어에는 Intel과 AT&T 문법이 존재

  • 윈도우는 Intel 문법, 리눅스는 AT&T 문법 주로 사용

  • 두 문법의 차이점은 제1피연산자와 제2피연산자의 위치

  • Intel 문법은 목적지가 앞에 오고 원본이 뒤에 오지만, AT&T 문법은 반대

 

1-1. 어셈블리어 명령 형식 (Intel 문법)

  • Label  : (라벨)

  • MOV (작동 코드)

  • AX (제1피연산자)

  • BX (제2피연산자)

  • ; comment (설명)

 

MOV는 제2피연산자 값을 제1피연산자로 복사하는 명령이다.

 

라벨은 기계어 코드로 직접 번역하지 않고, 점프(분기) 명령 등에서 참조할 때 메모리 주소를 계산하는 데 사용한다.

 

사용법은 다음과 같다.

Label_1 : MOV AX, BX
         	...
         	...
         	JMP Label_1 (Label_1로 무조건 이동하라는 명령)

 

다음 코드는 MOV부터가 기계어로 번역되는 부분으로 어셈블리어 작동 코드(명령 코드)라고 한다.

 

그리고 피연산자는 레지스터, 문자, 숫자, 메모리 주소가 될 수 있다.


(2) 어셈블리어 데이터 타입과 리틀 엔디안 방식

2-1. 데이터 타입

  • 바이트(Byte) : 1바이트(8비트) 데이터 항목

  • 워드(word) : 2바이트(16비트) 데이터 항목

  • 더블 워드(Double word) : 4바이트(32비트) 데이터 항목

[그림 1] 어셈블리어 데이터 타입

 

 

2-2. 리틀 엔디안 방식

  • 데이터는 리틀 엔디안 방식에 따라 스택에 저장, 참조

  • 번지 두 개로 나누어 저장해야 하는 16비트 데이터의 경우 하위 바이트는 하위 번지 저장, 상위 바이트는 상위 번지 저장

  • 예로 HEX 값 0x34F3을 1500번지에 저장하기 위해 하위 값 0xF3은 1500번지에 저장하고, 상위 값 0x34는 1501번지에 저장 

주소 1500번지 1501번지
저장된 데이터 F3 34

[그림 2] 어셈블리어 데이터 타입별 메모리 저장 위치

 

2-3. 빅 엔디안 vs 리틀 엔디안

  • 메모리에 데이터를 저장하는 바이트 순서를 바이트 정렬이라 함

  • RISC 칩을 기반으로 한 IBM 컴퓨터 등은 빅 엔디안 방식 사용

  • 0x86, DEC 시스템 등은 리틀 엔디안 방식 사용

  • 빅 엔디안은 최상위 바이트(MSB)부터 차례로 저장하는 방식, 리틀 엔디안은 최하위 바이트(LSB)부터 차례로 저장하는 방식


(3) 어셈블리어 주소 지정 방식

  • 80x86 시스템에서는 메모리에 접근할 수 있도록 다양한 주소 지정 방식 제공

 

3-1. 레지스터 주소 지정

  • 일반적으로 생각하는 메모리에 접근하는 방식은 아님

  • 레지스터 주소 값을 직접 지정하여 복사하는 방식으로 처리 속도가 가장 빠름

 

다음 내용은 BX 레지스터 내용을 DX 레지스터로 복사하는 명령의 예이다.

MOV DX, BX

 

3-2. 직접 메모리 주소 지정

  • 가장 일반적인 주소 지정 방식

  • 피연산자 하나가 메모리 위치를 참조하고, 다른 하나는 레지스터를 참조

  • 두 피연산자가 메모리를 직접 참조하는 것은 MOVS와 CMPS만 가능

 

다음 내용은 메모리 주소를 레지스터에 복사하고 레지스터를 메모리에 저장하는 두 가지 명령의 예이다.

MOV AL, DS:[8088h]
MOV DS:[1234h], DL

 

예에서 DS:[8088h]와 DS:[1234h]는 각각 '세그먼트:오프셋' 형식으로 메모리에 직접 접근하는 방식이다.

 

[그림 3] 직접 메모리 주소 지정 예

 

위 그림과 같이 각각 메모리에 접근한다.

 

 

3-3. 레지스터 간접 주소 지정

  • 직접 메모리 주소 방식처럼 '세그먼트:오프셋' 형식 사용

  • 단지 세그먼트를 명시적으로 적지 않음

MOV AL, [BX]
MOV AL, [BP]

[BX]와 [BP]는 실제로는 DS:BX, SS:BP 주소를 가리킨다.

 

[그림 4] 레지스터 간접 주소 지정 예

 

 

그리고 다음과 같이 기본이 아닌 세그먼트를 강제로 지정할 수도 있다.

MOV AL, CS:[BX]
MOV AL, DS:[BP]

 

3-4. 인덱스 주소 지정

  • 레지스터 간접 지정 방식에 변위가 더해진 메모리 주소 지정 방식

 

다음은 20h만큼 더해 메모리를 참조한 명령의 예이다.

MOV AL, [BX+20h]
MOV AL, [BP+20h]

 

위 예에서 [BX+20h]와 [BP+20h]는 DS:[BX+20h], SS:[BP+20h] 주소를 가리킨다.

 

[그림 5] 인덱스 주소 지정 예

 

위의 예는 다음과 같이 바꾸어 표현할 수 있다.

MOV AL, 20h[BX]
MOV AL, 20h[BP]

 

 

3-5. 베이스 인덱스 주소 지정

  • 실제 주소를 생성하기 위해 베이스 레지스터(BX 또는 BP)와 인덱스 레지스터(DI 또는 SI)를 결합

 

다음 예처럼 베이스 레지스터(BX 또는 BP)와 인덱스 레지스터(DI 또는 SI)를 결합한다.

MOV AL, [BX+SI]
MOV AL, [BP+SI]

 

[그림 6] 베이스 인덱스 주소 지정 예

 

 

베이스 인덱스 주소 지정도 인덱스 주소 지정처럼 다음과 같이 바꾸어 표현이 가능하다.

MOV AL, [BX][SI]
MOV AL, [BP][SI]

 

베이스 인덱스 주소 지정은 보통 2차원 배열 주소를 지정할 때 사용한다.

 

 

 

3-6. 변위를 갖는 베이스 인덱스 주소 지정

  • 베이스-인덱스 변형으로 실제 주소를 생성하려고 베이스 레지스터, 인덱스 레지스터, 변위를 결합

 

다음과 같이 표현할 수 있다.

MOV AL, [BX+SI+20h]
MOV AL, [BP+SI+20h]

[그림 7] 변위를 갖는 베이스 인덱스 주소 지정 예

 

 

변위를 갖는 베이스 인덱스 주소 지정 방식도 인덱스 주소 지정 방식처럼 다음과 같이 바꾸어 표현 가능하다.

MOV AL, [BX][SI][20h]
MOV AL, [BP][SI][20h]

# Reference

 

https://www.hanbit.co.kr/store/books/look.php?p_code=B3283906872

+ Recent posts