gcc:命令行参数在汇编代码中引用不同

时间:2013-11-25 22:15:15

标签: c gcc assembly command-line x86

我习惯看到(约定(A))引用的命令行参数:

pushl %ebp  
movl %esp, %ebp  
movl (%ebp), %eax    # argc  
movl 4(%ebp), %ebx   # pointer to argv[0] string      
movl 8($ebp), %ecx   # pointer to argv[1] string

有时,我看到列表的偏移量为8,这不是(主要)问题。我在程序中注意到的是这个我很困惑的翻译和参考,以获得argv[1](约定(B)):

movl 0xc(%ebp), %eax   # pointer to a pointer to argv[0] (argc is at offset 8)  
addl $0x4, %eax    # argv[1] is a pointer at offset 4 from the pointer to argv[0]   
movl (%eax), %eax    # load where it points to, which is the argv[1] string  

(在偏移16(%ebp)我看到一个指向环境变量的指针)

(1)这种不同的惯例是否有任何理由? (2)是否有编译器选项强制gcc使用我认为是上述标准惯例(A)? (3)gcc是否使用惯例(B)?
(4)为什么附加偏移量为8?

系统信息:
- Ubuntu 12.04
- gcc 4.6.3
- 使用fno-stack-protector编译

1 个答案:

答案 0 :(得分:1)

如果您正在处理已链接到C运行时的程序,则argcargv参数将通过argc传递(假设为x86){{1}在ebp+8 {}}和argv。那是因为C运行时执行它自己的初始化并使用正常的C ABI将参数传递给ebp+12

你说你习惯看到的调用约定(在堆栈顶部有main(),后跟argc .. argv[0])是堆栈的状态由启动新程序的Linux系统调用设置。

请注意面向程序集的代码示例:

argv[argc]
由于最初的pushl %ebp movl %esp, %ebp movl (%ebp), %eax # argc movl 4(%ebp), %ebx # pointer to argv[0] string movl 8($ebp), %ecx # pointer to argv[1] string 指令,

对于最后三行中的每一行看起来都是4。