Ich ging kürzlich durch eine Assembler-Sprachbuch von Richard Blum, wo es ein Thema auf dem C-Programm zu Assembly-Konvertierung war.Wie wirken ESP- und EBP-Register, wenn ein neues Programm ausgeführt wird?
Betrachten Sie das folgende C-Programm:
#include <stdio.h>
int main(){
int a=100;
int b=25;
if (a>b)
printf("The higher value is %d\n", a);
else
printf("The higher value is %d\n", b);
return 0;
}
, wenn ich das obige Programm mit -S
Parameter zusammengestellt wie:
gcc -S abc.c
ich folgendes Ergebnis bekam:
.file "abc.c"
.section .rodata
.LC0:
.string "The higher value is %d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
leal 4(%esp), %ecx
.cfi_def_cfa 1, 0
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
.cfi_escape 0x10,0x5,0x2,0x75,0
movl %esp, %ebp
pushl %ecx
.cfi_escape 0xf,0x3,0x75,0x7c,0x6
subl $20, %esp
movl $100, -16(%ebp)
movl $25, -12(%ebp)
movl -16(%ebp), %eax
cmpl -12(%ebp), %eax
jle .L2
subl $8, %esp
pushl -16(%ebp)
pushl $.LC0
call printf
addl $16, %esp
jmp .L3
.L2:
subl $8, %esp
pushl -12(%ebp)
pushl $.LC0
call printf
addl $16, %esp
.L3:
movl $0, %eax
movl -4(%ebp), %ecx
.cfi_def_cfa 1, 0
leave
.cfi_restore 5
leal -4(%ecx), %esp
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005"
.section .note.GNU-stack,"",@progbits
Was ich kann nicht verstehen, ist dies:
Snippet
.LFB0:
.cfi_startproc
leal 4(%esp), %ecx
.cfi_def_cfa 1, 0
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
.cfi_escape 0x10,0x5,0x2,0x75,0
movl %esp, %ebp
pushl %ecx
.cfi_escape 0xf,0x3,0x75,0x7c,0x6
subl $20, %esp
Ich bin nicht in der Lage, vorherzusagen, was mit dem Register ESP
und EBP
geschieht. Über EBP
kann ich bis zu einem gewissen Grad verstehen, dass es als lokaler Stapel verwendet wird, und so wird sein Wert durch das Aufschieben auf den Stapel gespart.
Können Sie bitte das obige Snippet ausarbeiten?
Es ist nur den Stapelzeiger auf 16-Byte-Grenze ausgerichtet werden. "ebp" wird auf den Stapel geschoben, da es sich um ein gespeichertes Register handelt. Es muss nicht als Rahmenzeiger verwendet werden, obwohl es in diesem Code ist. – Jester