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

标签 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
- 海合会 4.6.3
- 使用 fno-stack-protector 编译

最佳答案

如果您正在处理一个已链接到 C 运行时的程序,则 argcargv 参数将通过(假设为 x86) argcebp+8argvebp+12。这是因为 C 运行时执行它自己的初始化并使用普通 C ABI 将参数传递给 main()

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

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

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

由于初始 pushl 指令,最后三行中的每一行看起来都偏移了 4。

关于c - gcc:汇编代码中不同引用的命令行参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20204494/

相关文章:

c - 即使进程未刷新,cmd.exe 如何显示标准输出?

c - 通过指向指针参数的指针进行分配

c - 如何优化KASUMI算法的S盒?

c - 为什么这个简单的代码带有 printf "freeze"?

c - 如何在 FFmpeg 代码 (C) 中设置帧速率/FPS?

c - c : unsigned int to float 中的类型强制

c++ - 在 Qt C++ 上运行 dlib

gcc - 如何将gcc编译器的输出重定向到文件?

assembly - 反汇编PDP-8程序

c - 在 C 中使用 ASM 命令