分析生成的汇编代码以操作命令行参数

时间:2012-02-27 21:46:28

标签: c assembly x86 ia-32

#include <stdio.h>
int main(int argc, char * argv[])
{
 argv[1][2] = 'A';
 return 0;
}

以下是GCC针对32位Intel架构的相应汇编代码。我无法完全理解发生了什么。

main:
        leal    4(%esp), %ecx  - Add 4 to esp and store the address in ecx
        andl    $-16, %esp  - Store first 28 bits from esp's address into esp??
        pushl   -4(%ecx)  - Push the old esp on stack
        pushl   %ebp         - Preamble
        movl    %esp, %ebp
        pushl   %ecx          - push old esp + 4 on stack
        movl    4(%ecx), %eax   - move ecx + 4 to eax. this is the address of argv. argc stored at (%ecx).
        addl    $4, %eax - argv[1]
        movl    (%eax), %eax - argv[1][0]
        addl    $2, %eax  - argv[1][2]
        movb    $65, (%eax) - move 'A'
        movl    $0, %eax - move return value (0)
        popl    %ecx - get old value of ecx
        leave
        leal    -4(%ecx), %esp  - restore esp
        ret

前言中代码开头的内容是什么?根据以下代码,argv存储在哪里?在堆栈上?

2 个答案:

答案 0 :(得分:5)

您看到的有趣代码(前两行)是堆栈对齐为16个字节(-16~15相同,而x & ~15将x舍入为x是16的倍数。

输入函数时,

argv将存储在ESP + 8leal 4(%esp), %ecx所做的是创建指向包含argcargv的伪结构的指针,然后它继续从那里访问它们。 movl 4(%ecx), %eax从此伪结构中访问argv

答案 1 :(得分:1)

argv是“main()”的参数,因此在许多ABI中,它确实会在堆栈上传递。