컴퓨터과학

어셈블리어에 관한 통찰

영웅*^%&$ 2018. 10. 8. 15:09
728x90

void calc_sum(int n, int*sump)

{

int i, sum = 0;

 

for ( i=1; i<=n; I++ )

sum += i;

*sump=sum;

}

c언어 프로그래밍

 

cal_sum:

push ebp

mov ebp, esp

sub esp, 4

 

mov dword [ebp 4], 0 ;sum = 0

mov ebx, 1 ; ebx (i) = 1

for_loop:

cmp ebx, [ebp+8] ;i <= n인가?

jnle end_for

add [ebp-4], ebx ; sum += I

inc ebx

jmp short for_loop

end_for:

mov ebx, [ebp+12] ;ebx = sump

mov eax, [ebp-4] ;eax = sum

mov [ebx], eax ;*sump = sum;

 

mov esp, ebp

pop ebp

ret

 

어셈블리어 버전

직접 눈으로 봐도 알 수 있듯이 c언어보다 어셈블리어는 조금 더 상세합니다 물론 그 대신 직접적인 부분까지도 다루는 것이 가능하고 cpu를 직접 제어할 수 있습니다 그래서 고급언어로 구현할 수 없는 세부적인 부분까지도 구현할 수 있습니다 그렇기 때문에 악성코드 분석, 리버스 엔지니어링 등 컴퓨터 보안과 관련된 다양한 분야에서 사용됩니다

 

 

 

segment .data

x dd 0

format db “x = %d\n”, 0

 

segment .text

...

push dword [x]

push dword format

call _printf ;_에 주목

add esp, 8

printf로 호출한 프로그램입니다

고급언어는 어셈블리어처럼 상세하지는 않더라도

훨씬 우리의 자연어와 가까워서 사용하기 편리할뿐만 아니라 이식성도 굉장히 뛰어납니다

그래서 요새는 고급언어를 훨씬 더 많이 (프로그램에) 사용하는 추세입니다

(폰 노이만은 어셈블리어를 만드는 것조차 반대했다고 하니 아마 지금 세상에 오면 기분이 많이 상할 듯 합니다)

 

;finds n!

segment .text

global _fact

_fact:

enter 0,0

mov eax, [ebp+8] ;eax = n

cmp eax, 1

jbe term_cond

dec eax

push eax

call _fact

pop ecx

mul dword [ebp+8]

jmp short end_fact

term_cond:

mov eax, 1

end_fact:

leave

ret

재귀 팩토리얼 함수

 

 

 

void f(int x)

{

int i;

for( i=0; i < x; i++ ) {

printf(“%d\n“, i);

f(i);

}

}

c버전

 

%define i ebp-4

%define x ebp=8

segment .data

format db “%d”, 10, 0

segment .text

global _f

extern _printf

_f:

enter 4,0

mov dword [i], 0 ; i = 0

Ip:

mov eax, [i]

cmp eax, [x]

jnl quit

push eax ;printf 호출

push format

call _printf

add esp, 8

push dword [i]

call _f

pop eax

inc dword [i]

jmp short lp

quit :

leave

ret

어셈블리 버전

 

레지스터는 극히 소량의 데이터를 일시적으로 기억해두는 고속의 전용역역입니다

cpu내부 임시메모리 중 속도가 가장 빠릅니다

여러 종류의 레지스터들이 있습니다

 

1)플래그 레지스터(32bits)

EFLAG : 여러 가지 플래그 값을 저장합니다

2) 인덱스 레지스터(32bits)

EDI : 목적지에 대한 값을 저장합니다

ESI : 출발지에 대한 값을 저장합니다

3) 포인터 레지스터 (32bits)

EBP : 스택 내의 변수 값을 읽는 데 사용됩니다

ESP : 스택의 가장 끝 주소를 가르킵니다

EIP : 다음 실행될 명령어의 주소가 저장됩니다

4) 세그먼트 레지스터 (16bits)

CS : 기계명령어가 저장된 메모리 주소 지정합니다

DS : 정의된 데이터, 상수, 작업 영역의 주소 지정합니다

SS : 임시 저장 정보, 함수 호출에 관련된 정보를 저장합니다

5) 32bits 범용 레지스터

EAX : 함수의 리턴값이 저장되는 곳입니다

EBX : 특정 주소 저장, 간접 주소를 지정하는데 사용됩니다

ECX : 반복 카운터

EDX : 주로 EAX 보조로 사용되며 일반적인 자료를 저장합니다

 

지금까지 어셈블리어(고급언어인 c언어랑 비교해서)하고 레지스터의 역할을 간략하게 살펴보았습니다 흠 좀더 생각을 진행해볼까요? 어셈블리어하고 레지스터의 관계는 무엇일까요? 어셈블리어는 cpu를 거의 직접적으로 다룹니다(1:1관계이기 때문이지요) 그리고 레지스터는 cpu속 메모리이기때문에 둘 다 프로그램의 구동에 큰 역할을 한다고 할 수 있습니다 어셈블리어를 활용해서 프로그램 속 메모리들을 되짚어 볼 수 있고 그게 곧 레지스터로 연결되는 것이죠 프로그램을 거꾸로 되짚어 보는 과정을 리버스엔지니어링이라고합니다 그래서 다른 말로는 어셈블리어나 레지스터나 프로그램하고 연결되고 좀 더 기술적으로는 리버스엔지니어링에서 사용된다고 할 수 도 있겠네요(꼭 그런 것만은 아닙니다)


728x90

'컴퓨터과학' 카테고리의 다른 글

알파고는 계단을 걷지 못한다  (0) 2018.11.14
매크로에 관한 통찰   (0) 2018.10.08
간단한 데이터 압축   (0) 2018.10.08
인공지능의 사기적인 능력  (0) 2018.08.27
빅데이터   (0) 2018.03.07