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是的,您是对的。非常感谢。这应该是答案