x32 x64 어셈블리 실행시 메모리 사용 .. 01_셋팅하기
스압주의...
x32 (32비트 컴퓨터) -- 레지스터가 4 Byte 씩 실행되는 구조이다
x64 (64비트 컴퓨터) -- 레지스터가 8 Byte 씩 실행되는 구조이다 -- 요즘 거의 사용하는 형태
기계어(어셈블리) 디버깅 과정을 통해
해당 명령어 (mov, sub 등..) 수행하면서
메모리 할당을 어떻게 받고, 레지스터의 각 역할 및 사용 등을 확인해 볼 수 있다.
#include <stdio.h> int my_func(int n){ return n* 2; } int main(void){ int n = 3, res; res = my_func(n); printf("res = %d\n", res); return 0; } |
0x0000000000400534 <+0> : push %rbp 0x0000000000400535 <+1> : mov %rsp, %rbp 0x0000000000400538 <+4> : sub $0x10, %rsp 0x000000000040053c <+8> : movl $0x3, -0x8(%rbp) 0x0000000000400543 <+15> : mov -0x8(%rbp), %eax 0x0000000000400546 <+18> : mov %eax, %edi 0x0000000000400548 <+20> : callq 0x400526 <my_func> 0x000000000040054d <+25> : mov %eax, -0x4(%rbp) 0x0000000000400550 <+31> : mov -0x4(%rbp), %eax 0x0000000000400553 <+31> : mov %eax, %esi 0x0000000000400555 <+33> : mov $0x4005f4, %edi 0x000000000040055a <+38> : mov $0x0, %eax 0x000000000040055f <+43> : callq 0x400400 <printf@plt> 0x0000000000400564 <+48> : mov $0x0, %eax 0x0000000000400569 <+53> : leaveq 0x000000000040056a <+54> : retq |
아래 사항을 확인해보기 위한.. 리눅스 기본 Setting
1. vi [파일이름.c] >>> insert 키를 누르고 >>> 왼쪽 위 의 코드 작성하기
2. 작성을 완료하였다면, gdb 를 사용할 수 있도록 컴파일하기
gcc -g -o [파일의별칭아무거나] [파일이름.c]
3. 컴파일이 성공하였다면, gdb 소환
gdb [파일의별칭설정한것]
4. gdb 소환에 성공하였다면, breakpoint 을 main 으로 잡기
b main
5. 실행하기
r
6. 디버깅 전체보기
disas
7. 그러면 현재 화살표가 가리키고 있는 곳이 breakpoint 로 잡혀있는 것을 확인할 수 있다.
디버깅을 첫줄부터 시도해보기 위해...
맨 윗줄의 0x0000000000400534 긁어서 >>> 오른클릭 >>> 복사
8. breakpoint 추가하기 / 주의할 점은.. *을 붙인다는 것
b *0x0000000000400534
9. breakpoint 가 잘 잡혔는지 확인해보기
info b
그럼 잡혀있는 것이 2개 뜨지?
10. 잘 잡힌것을 확인했다면, 다시 실행하기(재시작)
r
11. 다시 실행 후 현재 화살표가 가리키고 있는 곳이 첫 줄임을 확인하자
disas
12. 여기까지 잘 따라왔다면.. 디버깅을 한 줄씩 해보면서,
실제 각 레지스터의 역할과 데이터가 메모리상에서 어떻게 처리되는지를 확인해 볼 수 있다.
어셈블리어 단위로 1 줄 진행하기 : si
C언어 단위로 1 줄 진행하기 : s
=================== 셋 팅 완 료 ===================
[참고] '%'는 레지스터 사용시 활용, '$'는 상수값 사용시 활용
[참고] p/x $레지스터이름 :