Устранение неполадок смысла этого кода ASM x86

Прежде всего, вот код ассемблера:

/           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

2 ответа

Решение

Линии отделены друг от друга:

Первая строка принадлежит строке char* a = "AAAA";, сохраняя значение переменной в 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 регистр. Такая память используется компилятором для локальных переменных, то есть "локальной" в том, что показывает дизассемблер.

Другие вопросы по тегам