C-访问函数内部的参数
我有一个C-访问函数内部的参数,c,gcc,assembly,C,Gcc,Assembly,我有一个main.c文件 int boyut(const char* string); char greeting[6] = {"Helle"}; int main(){ greeting[5] = 0x00; int a = boyut(greeting); return 0; } int boyut(const char* string){ int len=0; while(string[len]){ len++; }
main.c
文件
int boyut(const char* string);
char greeting[6] = {"Helle"};
int main(){
greeting[5] = 0x00;
int a = boyut(greeting);
return 0;
}
int boyut(const char* string){
int len=0;
while(string[len]){
len++;
}
return len;
}
我使用GCC
命令GCC-Wall-m32-nostlib main.c-o main.o
当我检查反汇编时,我看到变量greeting
被放置在.data
段中。在调用boyut
之前,它不会被推入堆栈。在boyut
函数中,它的行为就像变量greeting
在堆栈段中一样。所以这个变量实际上在函数内部没有被访问。为什么它会生成这样的代码?我怎样才能纠正这个问题
Disassembly of section .text:
080480f8 <main>:
80480f8: 55 push ebp
80480f9: 89 e5 mov ebp,esp
80480fb: 83 ec 18 sub esp,0x18
80480fe: c6 05 05 a0 04 08 00 mov BYTE PTR ds:0x804a005,0x0
8048105: 83 ec 0c sub esp,0xc
8048108: 68 00 a0 04 08 push 0x804a000
804810d: e8 0d 00 00 00 call 804811f <boyut>
8048112: 83 c4 10 add esp,0x10
8048115: 89 45 f4 mov DWORD PTR [ebp-0xc],eax
8048118: b8 00 00 00 00 mov eax,0x0
804811d: c9 leave
804811e: c3 ret
0804811f <boyut>:
804811f: 55 push ebp
8048120: 89 e5 mov ebp,esp
8048122: 83 ec 10 sub esp,0x10
8048125: c7 45 fc 00 00 00 00 mov DWORD PTR [ebp-0x4],0x0
804812c: eb 04 jmp 8048132 <boyut+0x13>
804812e: 83 45 fc 01 add DWORD PTR [ebp-0x4],0x1
8048132: 8b 55 fc mov edx,DWORD PTR [ebp-0x4]
8048135: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
8048138: 01 d0 add eax,edx
804813a: 0f b6 00 movzx eax,BYTE PTR [eax]
804813d: 84 c0 test al,al
804813f: 75 ed jne 804812e <boyut+0xf>
8048141: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
8048144: c9 leave
8048145: c3 ret
main.o: file format elf32-i386
Contents of section .data:
804a000 48656c6c 6500 Helle.
节的反汇编。文本:
080480f8:
80480f8:55推动ebp
80480f9:89 e5 mov ebp,esp
80480fb:83 ec 18子esp,0x18
80480fe:c6 05 05 a0 04 08 00 mov字节PTR ds:0x804a005,0x0
8048105:83 ec 0c子esp,0xc
8048108:68 00 a0 04 08推送0x804a000
804810d:e8 0d 00 00呼叫804811f
8048112:83 c4 10添加esp,0x10
8048115:89 45 f4 mov DWORD PTR[ebp-0xc],eax
8048118:B800 mov eax,0x0
804811d:c9离开
804811e:c3 ret
0804811f:
804811f:55推式ebp
8048120:89 e5 mov ebp,esp
8048122:83 ec 10子esp,0x10
8048125:c7 45 fc 00 mov DWORD PTR[ebp-0x4],0x0
804812c:eb 04 jmp 8048132
804812e:83 45 fc 01添加DWORD PTR[ebp-0x4],0x1
8048132:8b 55 fc mov edx,DWORD PTR[ebp-0x4]
8048135:8b 45 08 mov eax,DWORD PTR[ebp+0x8]
8048138:01 d0添加eax、edx
804813a:0f b6 00 movzx eax,字节PTR[eax]
804813d:84 c0测试铝,铝
804813f:75 ed jne 804812e
8048141:8b 45 fc mov eax,DWORD PTR[ebp-0x4]
8048144:c9离开
8048145:c3 ret
main.o:文件格式elf32-i386
第节内容。数据:
804a000 48656C66500 Helle。
函数boyut
声明如下:
int boyut(const char* string);
这意味着:boyut
获取指向char
的指针,并返回int
。实际上,编译器将一个点推送到堆栈上的char
。此指针指向问候语的开头。这是因为在C语言中,数组在大多数情况下隐式转换为指向其第一个元素的指针
如果要将数组传递给函数以便将其复制到函数中,则必须将数组包装成一个结构并传递该结构。函数boyut
的声明如下:
int boyut(const char* string);
这意味着:boyut
获取指向char
的指针,并返回int
。实际上,编译器将一个点推送到堆栈上的char
。此指针指向问候语的开头。这是因为在C语言中,数组在大多数情况下隐式转换为指向其第一个元素的指针
如果要将数组传递给函数,以便将其复制到函数,您必须将数组包装成一个结构并传递它。使用gcc-Wall-m32-O1-fverbose asm-S main.c
编译,然后查看生成的main.S
汇编文件并研究系统的ABI规范推送0x804a000
@dhke是的,您是对的。非常感谢。这应该是使用gcc-Wall-m32-O1-fverbose asm-S main.c
编译的答案,然后查看生成的main.S
汇编文件并研究系统的ABI规范push 0x804a000
@dhke是的,您是对的。非常感谢。这应该是答案