Ich übe derzeit mit dem Lesen der Baugruppe, indem ich C-Programme zerlege und versuche zu verstehen, was sie tun.Assembly - Übergeben von Parametern an einen Funktionsaufruf
Ich bin mit einem trivialen stecken: ein einfaches Hallo Welt Programm.
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello, world!");
return(0);
}
Wenn ich die Haupt zerlegen:
(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
Ich verstehe die ersten zwei Zeilen: der Basiszeiger wird auf dem Stapel gespeichert (durch Druck RBP, die den Wert des Stapelzeigers bewirkt, daß um 8 verringert, weil es "gewachsen" ist) und der Wert des Stapelzeigers im Basiszeiger gespeichert wird (so dass Parameter und lokale Variable leicht durch positive bzw. negative Offsets erreicht werden können, während der Stack "wachsen" kann) ").
Die dritte Zeile stellt das erste Problem dar: Warum wird 0x4005c4 (die Adresse der Zeichenfolge "Hello, World!") Im EDI-Register verschoben, anstatt es auf dem Stapel zu verschieben? Sollte die printf-Funktion nicht die Adresse dieser Zeichenkette als Parameter annehmen? Soweit ich weiß, nehmen Funktionen Parameter aus dem Stapel (aber hier sieht es so aus, als wäre der Parameter in diesem Register: edi)
In einem anderen Beitrag hier auf StackOverflow habe ich gelesen, dass "printf @ ptl" wie ein Stub ist Funktion, die die echte printf-Funktion aufruft. Ich habe versucht, diese Funktion zu zerlegen, aber es wird noch verwirrender:
(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.
Die beiden mov Operationen auf EAX (mov eax, 0x0) stört mich ein wenig, als gut, da ich sie nicht Rolle bekommen hier (Aber ich beschäftige mich mehr mit dem, was ich gerade beschrieben habe). Vielen Dank im Voraus.
Suche nach [X86-64 Funktion Args Stack] (http://StackOverflow.com/search?q=x86-64+Function+args+Stack) findet Tonnen verwandter Fragen. Keiner von denen, die ich angeschaut habe, scheint ein genaues Duplikat zu sein, aber wenn du das nächste Mal verwirrt bist, suche bitte nach den relevanten Stichwörtern. –
Als ein Vorschlag kann das Zerlegen von der Hauptleitung manchmal schwierig sein. Es ist fast immer einfacher, mit dem Aufruf einer Funktion von main und disassembling anzufangen. –