Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 此asm x86代码的故障排除_C_Assembly_X86_Instructions - Fatal编程技术网

C 此asm x86代码的故障排除

C 此asm x86代码的故障排除,c,assembly,x86,instructions,C,Assembly,X86,Instructions,首先,这里是汇编程序代码: / 0x000006a0 55 push rbp | 0x000006a1 4889e5 mov rbp, rsp | 0x000006a4 4883ec10 sub rsp, 0x10

首先,这里是汇编程序代码:

/           0x000006a0      55             push rbp                             
|           0x000006a1      4889e5         mov rbp, rsp                         
|           0x000006a4      4883ec10       sub rsp, 0x10                        
|           0x000006a8      488d05b50000.  lea rax, str.AAAA           ; 0x764  

|           0x000006af      488945f8       mov qword [local_8h], rax  
|           0x000006b3      488b45f8       mov rax, qword [local_8h]

|           0x000006b7      4889c6         mov rsi, rax                         
|           0x000006ba      488d3da80000.  lea rdi, 0x00000769         ; "%s"   
|           0x000006c1      b800000000     mov eax, 0                           
|           0x000006c6      e895feffff     call sym.imp.printf         ;[2] ; i 
|           0x000006cb      b800000000     mov eax, 0                           
|           0x000006d0      c9             leave                                
\           0x000006d1      c3             ret  
对于此c程序:

#include <stdio.h>
#include <string.h>

int main(){

    char* a = "AAAA";

    printf("%s", a);
    return 0;
}
这两个指令的意义是什么?我只看到同样的指令是单向的,而不是反向的。但为什么呢

以下是可执行文件的一些进一步信息:

blksz    0x0
block    0x100
fd       6
file     demo
format   elf64
iorw     false
mode     -r--
size     0x20e0
humansz  8.2K
type     DYN (Shared object file)
arch     x86
binsz    6559
bintype  elf
bits     64
canary   false
class    ELF64
crypto   false
endian   little
havecode true
intrp    /lib64/ld-linux-x86-64.so.2
lang     c
linenum  true
lsyms    true
machine  AMD x86-64 architecture
maxopsz  16
minopsz  1
nx       true
os       linux
pcalign  0
pic      true
relocs   true
relro    partial relro
rpath    NONE
static   false
stripped false
subsys   linux
va       true

这些线彼此分开:

第一行属于行
char*a=“AAAA”,将变量值保存到RAM

第二行从RAM访问行
printf(“%s”,a)的变量作为参数

从技术上讲,这两行都是可选的,您可以这样写:

printf("%s", "AAAA");

编辑:要跳过这段不必要的代码,您可以启用自动优化(对于GCC:-O2)

问题在于您的反汇编程序已损坏(或至少“太聪明了”),并且“有用地”为您提供了与通常预期不同的、令人困惑的信息。这两条线:

|           0x000006af      488945f8       mov qword [local_8h], rax            
|           0x000006b3      488b45f8       mov rax, qword [local_8h]
应该是

|           0x000006af      488945f8       mov qword [rbp-8h], rax            
|           0x000006b3      488b45f8       mov rax, qword [rbp-8h]

它们通过
rbp
寄存器间接访问堆栈帧中的内存。编译器将这种内存用于局部变量,因此反汇编程序显示的是“局部”。

您应该检查非调试代码,即删除这些不必要存储的代码。编译器通常使用非常简单的规则将源代码分解为一系列基本步骤(有时称为“中间代码”)然后,他们优化中间代码以消除冗余或浪费的步骤。您似乎已在关闭优化的情况下编译了此代码。您在未进行优化的情况下编译了代码。毫不奇怪,当你告诉编译器不要优化时,编译器会发出无用的奇怪代码@fuz您的声明听起来有点像“编译器供应商通过在非优化输出中引入箔条来区分优化输出和非优化输出”。我想编译器供应商会认为这是一种侮辱。另外,根据我的经验,优化后的版本更奇怪,但原因很好,即使很复杂。@Yunnosch至少gcc关闭了寄存器分配,使用了更简单的指令选择器,并且在没有优化的情况下生成了额外的糟糕代码。这需要额外的代码来支持,所以从某种意义上说,是的,编译器编写者在没有优化的情况下确实会让代码变得更糟糕。或者,程序员可以打开优化,让编译器来完成,而不是从源代码中删除局部变量
a
。从这个简单的例子中可能看不出这一点,但是手工优化源代码通常会降低可读性,并且通常不如让编译器来做那样有效。你完全正确。我的例子应该说明为什么会出现装配线。OP并不是问
local_8h
是什么意思。OP询问第二条指令的目的是什么,当它加载到
rax
中的值不可能与
rax
中已有的值不同时?答案是,因为这两行中的每一行都是从不同的源代码行生成的,并且优化被关闭。
|           0x000006af      488945f8       mov qword [rbp-8h], rax            
|           0x000006b3      488b45f8       mov rax, qword [rbp-8h]