현재 C 프로그램을 디스 어셈블하고 해당 기능을 이해하려고 어셈블리 읽기를 연습하고 있습니다.어셈블리 - 함수 호출에 매개 변수 전달
나는 단순한 안녕하세요 세계 프로그램입니다. 내가 주를 분해
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello, world!");
return(0);
}
:
(gdb) disassemble main
Dump of assembler code for function main:
0x0000000000400526 <+0>: push rbp
0x0000000000400527 <+1>: mov rbp,rsp
0x000000000040052a <+4>: mov edi,0x4005c4
0x000000000040052f <+9>: mov eax,0x0
0x0000000000400534 <+14>: call 0x400400 <[email protected]>
0x0000000000400539 <+19>: mov eax,0x0
0x000000000040053e <+24>: pop rbp
0x000000000040053f <+25>: ret
나는 처음 두 줄의 이해 : 기본 포인터로 스택 포인터의 값을 발생 푸시 RBP에 의해 (스택에 저장됩니다 "성장"했기 때문에 8 씩 감소) 스택 포인터의 값이 기본 포인터에 저장 됨 (스택이 계속 성장할 수있는 동안 매개 변수와 로컬 변수가 각각 양수 및 음수 오프셋을 통해 쉽게 도달 할 수 있음) ").
세 번째 줄은 첫 번째 문제를 나타냅니다. 0x4005c4 ("Hello, World!"문자열의 주소)가 스택에서 이동하지 않고 edi 레지스터에서 이동 한 이유는 무엇입니까? printf 함수가 그 문자열의 주소를 매개 변수로 받아 들여야하지 않습니까? 내가 아는 한, 함수는 스택에서 매개 변수를 가져온다 (그러나 여기에서는 매개 변수가 그 레지스터에 저장되어있는 것처럼 보인다 : edi)
StackOverflow의 또 다른 게시물에서 "printf @ ptl"은 스텁과 같다. 실제 printf 함수를 호출하는 함수. EAX에
(gdb) disassemble printf
Dump of assembler code for function __printf:
0x00007ffff7a637b0 <+0>: sub rsp,0xd8
0x00007ffff7a637b7 <+7>: test al,al
0x00007ffff7a637b9 <+9>: mov QWORD PTR [rsp+0x28],rsi
0x00007ffff7a637be <+14>: mov QWORD PTR [rsp+0x30],rdx
0x00007ffff7a637c3 <+19>: mov QWORD PTR [rsp+0x38],rcx
0x00007ffff7a637c8 <+24>: mov QWORD PTR [rsp+0x40],r8
0x00007ffff7a637cd <+29>: mov QWORD PTR [rsp+0x48],r9
0x00007ffff7a637d2 <+34>: je 0x7ffff7a6380b <__printf+91>
0x00007ffff7a637d4 <+36>: movaps XMMWORD PTR [rsp+0x50],xmm0
0x00007ffff7a637d9 <+41>: movaps XMMWORD PTR [rsp+0x60],xmm1
0x00007ffff7a637de <+46>: movaps XMMWORD PTR [rsp+0x70],xmm2
0x00007ffff7a637e3 <+51>: movaps XMMWORD PTR [rsp+0x80],xmm3
0x00007ffff7a637eb <+59>: movaps XMMWORD PTR [rsp+0x90],xmm4
0x00007ffff7a637f3 <+67>: movaps XMMWORD PTR [rsp+0xa0],xmm5
0x00007ffff7a637fb <+75>: movaps XMMWORD PTR [rsp+0xb0],xmm6
0x00007ffff7a63803 <+83>: movaps XMMWORD PTR [rsp+0xc0],xmm7
0x00007ffff7a6380b <+91>: lea rax,[rsp+0xe0]
0x00007ffff7a63813 <+99>: mov rsi,rdi
0x00007ffff7a63816 <+102>: lea rdx,[rsp+0x8]
0x00007ffff7a6381b <+107>: mov QWORD PTR [rsp+0x10],rax
0x00007ffff7a63820 <+112>: lea rax,[rsp+0x20]
0x00007ffff7a63825 <+117>: mov DWORD PTR [rsp+0x8],0x8
0x00007ffff7a6382d <+125>: mov DWORD PTR [rsp+0xc],0x30
0x00007ffff7a63835 <+133>: mov QWORD PTR [rsp+0x18],rax
0x00007ffff7a6383a <+138>: mov rax,QWORD PTR [rip+0x36d70f] # 0x7ffff7dd0f50
0x00007ffff7a63841 <+145>: mov rdi,QWORD PTR [rax]
0x00007ffff7a63844 <+148>: call 0x7ffff7a5b130 <_IO_vfprintf_internal>
0x00007ffff7a63849 <+153>: add rsp,0xd8
0x00007ffff7a63850 <+160>: ret
End of assembler dump.
두 MOV 작업 여기에 그들에게 역할을하지 않기 때문에 (mov 인 EAX는 0x0으로는)뿐만 아니라, 나에게 조금 귀찮게 : 더 혼란 그 기능을 분해하려고하지만 도착 (그러나 나는 지금 막 기술 한 것에 더 관심이있다). 미리 감사드립니다.
[x86-64 함수 args 스택] (http://stackoverflow.com/search?q=x86-64+function+args+stack)에 대한 검색 관련 질문 내가 본 것 중 아무 것도 정확한 복제본처럼 보일 수는 없지만 다음 번에 혼란 스러울 때 관련 키워드 중 일부를 검색해보십시오. –
제안 사항에 따라 주에서 분해하는 것은 때로는 까다 롭습니다. main에서 함수를 호출하고 그 함수를 처음부터 다시 시작하는 것이 거의 언제나 쉽습니다. –