Der Titel ist eigentlich mein zweites Problem. 2 Probleme traten auf, als ich die 2. Auflage der CSAPP, Kapitel 3, lernte. Es gibt 2 relativ einfache Dateien. Hier ist die erste:Warum% esp wird imexplitcitly geändert?
// code.c
int accum = 0;
int sum(int x, int y)
{
int t = x + y;
accum += t;
return t;
}
Die zweite:
// main.c
int main() {
return sum(1, 3);
}
ich gcc verwendet, um sie zu erstellen, nach dem Buch. Um eine 32-Bit-Programm zu erhalten, habe ich eine -m32 Option (Meins ist 64-bit Ubuntu):
$ gcc -m32 -O1 -O prog code.c main.c
Dinge waren weit diese gut auf. Aber als ich es mit GDB zerlegte, verwirrte es mich wirklich. Ich habe das folgende Ergebnis, dass in Konflikt mit dem, was das Buch sagt:
(gdb) disas sum
Dump of assembler code for function sum:
0x080483ed <+0>: mov 0x8(%esp),%eax
0x080483f1 <+4>: add 0x4(%esp),%eax
0x080483f5 <+8>: add %eax,0x804a020
0x080483fb <+14>: ret
End of assembler dump.
(gdb) disas main
Dump of assembler code for function main:
0x080483fc <+0>: push %ebp
0x080483fd <+1>: mov %esp,%ebp
0x080483ff <+3>: and $0xfffffff0,%esp
0x08048402 <+6>: sub $0x10,%esp
0x08048405 <+9>: movl $0x3,0x4(%esp)
0x0804840d <+17>: movl $0x1,(%esp)
0x08048414 <+24>: call 0x80483ed <sum>
0x08048419 <+29>: leave
0x0804841a <+30>: ret
End of assembler dump.
Jetzt sind hier meine Probleme:
- Warum ist es eine Einsparung% ebp oder esp bewegen% beim Aufruf der Funktion Summe wie das Buch beschreibt? Oder ist Summe inlined vom Compiler?
Der Wert 3 & 1 wurde bereits im M [% esp + 4] & M [% esp] gespeichert. Und nach dem Aufruf der Summe gibt es keine Anweisung, die den in% esp gespeicherten Wert ändert. Aber innerhalb der Summe, die erste Anweisung ruft M [% esp + 8], die eigentlich 3 ist (Ich legte den Haltepunkt mit GDB & überprüfte den Wert), während die M [% esp + 4] den Wert 1 speichert. Woher? Später stellte ich 2 Stützpunkte:
(gdb) break *0x08048414 (gdb) break sum
Dann fand ich das in% esp gespeicherten Wert war anders an diesen 2 Stützpunkte:
Breakpoint 6, 0x08048414 in main()
(gdb) print $esp
$8 = (void *) 0xffffd020
(gdb) continue
Continuing.
Breakpoint 5, 0x080483ed in sum()
(gdb) print $esp
$9 = (void *) 0xffffd01c
Warum sollte dies geschehen?
Was ist mit 'push',' pop', 'call',' ret'? – tkausl
Es scheint seltsam, dass dieser Code erfolgreich kompiliert wurde, weil 'sum()' nicht in 'main.c' definiert ist. Ist das der eigentliche Code, den du kompiliert hast? –
@LiranFunaro Ich denke mit C und schlechten Compiler-Einstellungen wird es nur warnen "undefined, ich nehme an, es gibt int zurück und nimmt tatsächlich diese Argumente" –