【问题标题】:C - accessing parameter inside the functionC - 访问函数内的参数
【发布时间】:2017-05-27 17:25:12
【问题描述】:

我有一个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 -nostdlib 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. 

【问题讨论】:

  • 用gcc -Wall -m32 -O1 -fverbose-asm -S main.c编译然后查看生成的main.s汇编文件
  • 并为您的系统研究 ABI 规范
  • push 0x804a000 greeting的地址。当然,如果您检查.o 文件,您不应该忘记您仍然需要进行链接(以及符号重定位)。我认为您实际上应该看到一个占位符push $0x0。
  • @dhke 是的,你是对的。谢谢你!这应该是答案

标签: c gcc assembly


【解决方案1】:

函数boyut 声明如下:

int boyut(const char* string);

这意味着:boyut 接受一个指向char 的指针并返回一个int。事实上,编译器将一个点推送到堆栈上的char。该指针指向greeting 的开头。发生这种情况是因为在 C 语言中,在大多数情况下,数组会隐式转换为指向其第一个元素的指针。

如果要将数组传递给函数以便将其复制到函数中,则必须将数组包装到结构中并传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    • 1970-01-01
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多