Also muss ich ein Assembly-Programm schreiben, das extern C-Funktion aufrufen würde. Also schrieb ich einfach pow
Funktion, kompilierte ich mein Assembly-Programm mit diesem C-Code. Funktioniert alles. Aber wie ich aus -S
Befehl von gcc
sah, macht der Compiler einen Platz für lokale Variablen. Ich dachte, es so sein würde:Platz für lokale Variablen in Assembly machen
int func(int number)
{
int a = 10;
int b = 5;
int c = 0;
}
Wir haben drei lokale Variablen, so dass der Compiler würde subl $12, %esp
. Aber es geht für subl $16, %esp
. Selbst wenn ich hier nur eine Zahl belassen würde, würde sie trotzdem um 16
dekrementieren. Jetzt habe ich meinen Code:
main.s
:
.section .data
.XD:
msg: .ascii "%d\n"
msg_len = . - msg
.text
.globl _pow
.globl main
main:
pushl %ebp
movl %esp, %ebp
movl $5, %eax #like int a = 5;
pushl %eax
call _pow #_pow(a);
movl %eax, -8(%ebp)
pushl -8(%ebp)
pushl $.XD
call printf #printf("%d\n", _pow(a));
movl $0, %eax
leave
ret
func.c
:
int _pow(int number)
{
return number * number;
}
Es funktioniert wie erwartet, ./main
druckt 25
. Aber jetzt, ich habe keine subl
irgendetwas von %esp
. Ich meine, ich kann diese Zeile hinzufügen, aber es ändert nichts. Ich habe im Internet gesucht und herausgefunden, dass mein Code vielleicht nur zufällig funktioniert und ich sollte generell %esp
dekrementieren. Also meine Frage hier ist: Um welchen Wert sollte ich %esp
in main
dekrementieren? Sollte es 12
oder vielleicht 16
sein?
Die Verwendung von '16' ist sehr wahrscheinlich, dass der Stapel 16-Byte-ausgerichtet zu halten. – unwind
Ich denke, Sie haben Recht, aber sollte ich es dann immer 16-Byte ausgerichtet machen, oder sollte ich bestimmte Werte "unterbinden"? – Frynio
Die Anforderung wird wahrscheinlich in der ABI-Dokumentation (Application Binary Interface) der Plattform angegeben. Da es sich um eine Spezifikation handelt, sollten Sie sie befolgen, um mit anderem Code interagieren zu können. – unwind