Ich habe eine einfache Montage Programm geschrieben:Warum wird der Wert von EDX beim Aufruf von printf überschrieben?
section .data
str_out db "%d ",10,0
section .text
extern printf
extern exit
global main
main:
MOV EDX, ESP
MOV EAX, EDX
PUSH EAX
PUSH str_out
CALL printf
SUB ESP, 8 ; cleanup stack
MOV EAX, EDX
PUSH EAX
PUSH str_out
CALL printf
SUB ESP, 8 ; cleanup stack
CALL exit
Ich bin der NASM Assembler und der GCC die Objektdatei in eine ausführbare Datei auf Linux zu verknüpfen.
Im Wesentlichen setzt dieses Programm zuerst den Wert des Stapelzeigers in das Register EDX und druckt dann den Inhalt dieses Registers zweimal. Nach dem zweiten printf-Aufruf stimmt der Wert für das stdout jedoch nicht mit dem ersten überein.
Dieses Verhalten scheint seltsam. Wenn ich jede Verwendung von EDX in diesem Programm durch EBX ersetze, sind die ausgegebenen Ganzzahlen wie erwartet identisch. Ich kann nur folgern, dass EDX irgendwann während des printf-Funktionsaufrufs überschrieben wird.
Warum ist das der Fall? Und wie kann ich sicherstellen, dass die Register, die ich in Zukunft benutze, nicht mit den C-lib-Funktionen kollidieren?
Das hat mich auch vor Jahren das erste Mal bekommen. Die Antwort, die Sie angenommen haben, ist korrekt, lässt aber "ebp" und "esp" als Aufrufer weg. Diese beiden scheinen selbstverständlich zu sein, aber Sie können das technisch durcheinander bringen. Willkommen in der Montage! – sqykly
@sqykly Danke. Es ist sicherlich viel weniger nachsichtig als die höheren Sprachen, die ich gewohnt bin. Aber ich werde nicht davon besiegt werden! :) – Jake
Beantworten Sie so viele Javascript-Fragen wie ich und Sie werden sich darüber wundern. – sqykly