#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存储在哪里?在堆栈上?
答案 0 :(得分:5)
您看到的有趣代码(前两行)是堆栈对齐为16个字节(-16
与~15
相同,而x & ~15
将x舍入为x是16的倍数。
argv
将存储在ESP + 8
,leal 4(%esp), %ecx
所做的是创建指向包含argc
和argv
的伪结构的指针,然后它继续从那里访问它们。 movl 4(%ecx), %eax
从此伪结构中访问argv
。
答案 1 :(得分:1)
argv是“main()”的参数,因此在许多ABI中,它确实会在堆栈上传递。