C 代码编译成不正确的指令

问题描述 投票:0回答:1
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char** argv) {
  char *str5=malloc(10);
  *str5="xxxxx\0";
  printf("%s\n",str5);
  return 0;
}

编译成以下程序集(使用“gcc source.c”):

=> 0x555555555179 <main+4>:     sub    rsp,0x20
   0x55555555517d <main+8>:     mov    DWORD PTR [rbp-0x14],edi
   0x555555555180 <main+11>:    mov    QWORD PTR [rbp-0x20],rsi
   0x555555555184 <main+15>:    mov    edi,0xa
   0x555555555189 <main+20>:    call   0x555555555040 <malloc@plt>
   0x55555555518e <main+25>:    mov    QWORD PTR [rbp-0x8],rax
   0x555555555192 <main+29>:    lea    rax,[rip+0xe6b]        # 0x555555556004
   0x555555555199 <main+36>:    mov    edx,eax
   0x55555555519b <main+38>:    mov    rax,QWORD PTR [rbp-0x8]
   0x55555555519f <main+42>:    mov    BYTE PTR [rax],dl
   0x5555555551a1 <main+44>:    mov    rax,QWORD PTR [rbp-0x8]
   0x5555555551a5 <main+48>:    mov    rdi,rax
   0x5555555551a8 <main+51>:    call   0x555555555030 <puts@plt>
   0x5555555551ad <main+56>:    mov    eax,0x0
   0x5555555551b2 <main+61>:    leave
   0x5555555551b3 <main+62>:    ret
   0x5555555551b4 <_fini>:      sub    rsp,0x8
   0x5555555551b8 <_fini+4>:    add    rsp,0x8
   0x5555555551bc <_fini+8>:    ret

因此,在 main+42 上,它将 $dl 加载到 $rax 指向的地址中,即我的变量 str5。这最终只是一个垃圾角色。编译器发出以下警告,这可能是相关的,但我不明白如何:

source.c:6:14: warning: assignment to ‘char’ from ‘char *’ makes integer from pointer without a cast [-Wint-conversion]

为什么 gcc 这样编译这段代码?

c gcc
1个回答
0
投票

在 C

*str5="xxxxx\0";
中不复制字符串。

这个操作其实是:

  • 获取字符串文字的地址
    "xxxxx\0"
  • 将此地址转换为
    char
    (这是一个整数)
  • malloc
    分配的内存的第一个字符分配为该整数值

所以编译器是正确的,它正在为您编写的程序生成代码。

© www.soinside.com 2019 - 2024. All rights reserved.