#include <stdio.h>
int main()
{
int x;
printf("Enter x:\n");
scanf("%d", &x);
printf("you entered %d...\n", x);
return 0;
}
#if 0
/*
* x86
*/
在函数运行期间,EBP一直指向当前的栈帧(stack frame)。这样,函数即可能过EBP+offset的方式访问本地变量、以及外部传入的函数参数。
ESP也可以用来访问本地变量,获取函数所需的运行参数。不过ESP的值经常变化,用起来并不方便。函数在启动之初就会利用EBP保存ESP的
值。这就是为了确保在函数运行期间保证EBP存储的原始ESP值固定不变。
在32位系统里,典型的栈帧(stack frame)结构如下:
... ...
EBP-8 局部变量#2
EBP-4 局部变量#1
EBP ESP的值
EBP+4 返回地址
EBP+8 函数参数#1, IDA标记为arg_0
EBP+C 函数参数#2, IDA标记为arg_4
EBP+10 函数参数#3, IDA标记为arg_8
... ...
lea
load effective address,将源操作数(第二个参数)给出的效地址(offset)传送到目的寄存器(第一个参数)之中。
/*
* x64
*/
由于这个程序的参数较少,编译器会直接使用寄存器传递参数。
/*
* arm
*/
scan函数同样要借助指针传递返回值。
/*
* arm64
*/
add x1, x29, 28 # 分配局部变量 x 的存储空间。
#endif
#if 0
/*
* intel
*/
00000000000011a9 <main>:
11a9: f3 0f 1e fa endbr64
11ad: 55 push %rbp
11ae: 48 89 e5 mov %rsp,%rbp
11b1: 48 83 ec 10 sub $0x10,%rsp
11b5: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
11bc: 00 00
11be: 48 89 45 f8 mov %rax,-0x8(%rbp)
11c2: 31 c0 xor %eax,%eax
11c4: 48 8d 3d 39 0e 00 00 lea 0xe39(%rip),%rdi # 2004 <_IO_stdin_used+0x4>
11cb: e8 b0 fe ff ff callq 1080 <puts@plt> // puts()
11d0: 48 8d 45 f4 lea -0xc(%rbp),%rax // rax=rbp-0xc
11d4: 48 89 c6 mov %rax,%rsi // rsi=rax
11d7: 48 8d 3d 2f 0e 00 00 lea 0xe2f(%rip),%rdi # 200d <_IO_stdin_used+0xd> // rdi="%d"
11de: b8 00 00 00 00 mov $0x0,%eax
11e3: e8 c8 fe ff ff callq 10b0 <__isoc99_scanf@plt> // scanf(rdi, rsi)
11e8: 8b 45 f4 mov -0xc(%rbp),%eax // eax=x
11eb: 89 c6 mov %eax,%esi // esi=eax
11ed: 48 8d 3d 1c 0e 00 00 lea 0xe1c(%rip),%rdi # 2010 <_IO_stdin_used+0x10> // rdi="you entered %d...\n"
11f4: b8 00 00 00 00 mov $0x0,%eax
11f9: e8 a2 fe ff ff callq 10a0 <printf@plt> // printf(rdi, esi)
11fe: b8 00 00 00 00 mov $0x0,%eax
1203: 48 8b 55 f8 mov -0x8(%rbp),%rdx
1207: 64 48 33 14 25 28 00 xor %fs:0x28,%rdx
120e: 00 00
1210: 74 05 je 1217 <main+0x6e>
1212: e8 79 fe ff ff callq 1090 <__stack_chk_fail@plt>
1217: c9 leaveq
1218: c3 retq
1219: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
/*
* arm
*/
00000000004005fc <main>:
4005fc: a9be7bfd stp x29, x30, [sp, #-32]!
400600: 910003fd mov x29, sp
400604: 90000000 adrp x0, 400000 <_init-0x468>
400608: 911bc000 add x0, x0, #0x6f0
40060c: 97ffffb1 bl 4004d0 <puts@plt> // puts
400610: 910073a1 add x1, x29, #0x1c // x1 = x29+0x1c
400614: 90000000 adrp x0, 400000 <_init-0x468>
400618: 911c0000 add x0, x0, #0x700 // x0="you entered %d...\n"
40061c: 97ffffb1 bl 4004e0 <__isoc99_scanf@plt> // scanf(x0, x1)
400620: b9401fa1 ldr w1, [x29, #28]
400624: 90000000 adrp x0, 400000 <_init-0x468>
400628: 911c2000 add x0, x0, #0x708
40062c: 97ffffb1 bl 4004f0 <printf@plt>
400630: 52800000 mov w0, #0x0 // #0
400634: a8c27bfd ldp x29, x30, [sp], #32
400638: d65f03c0 ret
40063c: 00000000 .inst 0x00000000 ; undefined
#endif