排除此 asm x86 代码的意义
Troubleshooting the sense of this asm x86 code
首先,这里是汇编代码:
/ 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;
}
特别是我对这段代码有疑问:
| 0x000006af 488945f8 mov qword [local_8h], rax
| 0x000006b3 488b45f8 mov rax, qword [local_8h]
这两条指令的意义是什么?我只以一种方式看到相同的指令,而不是相反。但这是为什么呢?
以下是有关可执行文件的更多信息:
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。
第二行将printf("%s", a);
行的RAM变量作为参数访问
从技术上讲,这两行都是可选的,就像您可以写的那样:
printf("%s", "AAAA");
编辑: 要跳过这些不必要的代码,您可以启用自动优化(对于 GCC:-O2)
问题是您的反汇编程序已损坏(或至少 "too smart")并且 "helpfully" 给您提供了与通常预期不同的、令人困惑的信息。这两行:
| 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
寄存器间接访问堆栈帧中的内存。编译器将此类内存用于局部变量,因此反汇编程序显示的 "local"。
首先,这里是汇编代码:
/ 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;
}
特别是我对这段代码有疑问:
| 0x000006af 488945f8 mov qword [local_8h], rax
| 0x000006b3 488b45f8 mov rax, qword [local_8h]
这两条指令的意义是什么?我只以一种方式看到相同的指令,而不是相反。但这是为什么呢?
以下是有关可执行文件的更多信息:
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。
第二行将printf("%s", a);
行的RAM变量作为参数访问
从技术上讲,这两行都是可选的,就像您可以写的那样:
printf("%s", "AAAA");
编辑: 要跳过这些不必要的代码,您可以启用自动优化(对于 GCC:-O2)
问题是您的反汇编程序已损坏(或至少 "too smart")并且 "helpfully" 给您提供了与通常预期不同的、令人困惑的信息。这两行:
| 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
寄存器间接访问堆栈帧中的内存。编译器将此类内存用于局部变量,因此反汇编程序显示的 "local"。