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속 메모리이기때문에 둘 다 프로그램의 구동에 큰 역할을 한다고 할 수 있습니다 어셈블리어를 활용해서 프로그램 속 메모리들을 되짚어 볼 수 있고 그게 곧 레지스터로 연결되는 것이죠 프로그램을 거꾸로 되짚어 보는 과정을 리버스엔지니어링이라고합니다 그래서 다른 말로는 어셈블리어나 레지스터나 프로그램하고 연결되고 좀 더 기술적으로는 리버스엔지니어링에서 사용된다고 할 수 도 있겠네요(꼭 그런 것만은 아닙니다)
'컴퓨터과학' 카테고리의 다른 글
알파고는 계단을 걷지 못한다 (0) | 2018.11.14 |
---|---|
매크로에 관한 통찰 (0) | 2018.10.08 |
간단한 데이터 압축 (0) | 2018.10.08 |
인공지능의 사기적인 능력 (0) | 2018.08.27 |
빅데이터 (0) | 2018.03.07 |