我习惯于看到(约定(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元?
系统信息:
发布于 2013-11-26 00:35:31
如果您处理的是一个已经链接到C运行时的程序,那么argc和argv参数将被传递(假设是x86),argc在ebp+8上,argv在ebp+12上。这是因为C运行时执行自己的初始化,并使用普通的C将参数传递给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行。
https://stackoverflow.com/questions/20204494
复制相似问题