我只是好奇以下的例子
#include<stdio.h>
int test();
int test(){
// int a = 5;
// int b = a+1;
return ;
}
int main(){
printf("%u\n",test());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用'gcc -Wall -o semicolon semicolon.c'编译它来创建一个可执行文件和'gcc -Wall -S semicolon.c'来获取汇编代码,它是:
.file "semicolon.c"
.text
.globl test
.type test, @function
test:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
leave
ret
.size test, .-test
.section .rodata
.LC0:
.string "%u\n"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $20, %esp
call test
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
movl $0, %eax
addl $20, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
因为我不是这样的汇编程序专家,我只知道printf打印出eax中的内容,但我不完全理解'movl%eax,4(%esp)'意味着我在调用test之前假设填充eax但是那么值是什么?什么意思是4(%esp)和esp的意思是什么意思?
如果我取消注释test()printf中的行打印6 - 这是用eax ^^编写的
您的汇编语言注释:
test:
pushl %ebp # Save the frame pointer
movl %esp, %ebp # Get the new frame pointer.
subl $4, %esp # Allocate some local space on the stack.
leave # Restore the old frame pointer/stack
ret
Run Code Online (Sandbox Code Playgroud)
请注意,测试中没有任何内容涉及eax.
.size test, .-test
.section .rodata
.LC0:
.string "%u\n"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx # Point past the return address.
andl $-16, %esp # Align the stack.
pushl -4(%ecx) # Push the return address.
pushl %ebp # Save the frame pointer
movl %esp, %ebp # Get the new frame pointer.
pushl %ecx # save the old top of stack.
subl $20, %esp # Allocate some local space (for printf parameters and ?).
call test # Call test.
Run Code Online (Sandbox Code Playgroud)
请注意,此时,没有任何修改过的eax.无论是什么进入主要仍然在这里.
movl %eax, 4(%esp) # Save eax as a printf argument.
movl $.LC0, (%esp) # Send the format string.
call printf # Duh.
movl $0, %eax # Return zero from main.
addl $20, %esp # Deallocate local space.
popl %ecx # Restore the old top of stack.
popl %ebp # And the old frame pointer.
leal -4(%ecx), %esp # Fix the stack pointer,
ret
Run Code Online (Sandbox Code Playgroud)
因此,打印出来的是主要内容.正如其他人指出的那样,它是未定义的:它取决于启动代码(或操作系统)以前对eax做了什么.
分号没有返回值,你所拥有的是一个"空返回",就像用于从void函数返回的那个一样 - 所以函数不会返回任何内容.
这实际上在编译时会发出警告:
warning: `return' with no value, in function returning non-void
Run Code Online (Sandbox Code Playgroud)
eax在打电话之前我没有看到任何东西test.
大约4(%esp),这意味着从堆栈指针(esp)+ 4中获取值.即堆栈上的前一个字.
| 归档时间: |
|
| 查看次数: |
682 次 |
| 最近记录: |