Troubleshooting the sense of this asm x86 code

1

First of all, here is the assembler 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  

to this c program:

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

int main(){

    char* a = "AAAA";

    printf("%s", a);
    return 0;
}

Especially I have a question to this code snipped:

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

What is the sense of these two instructions? I only see the same instruction one way and than reversed. But why is that?

Here are some further information to the executable:

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
c
assembly
x86
instructions
asked on Stack Overflow May 31, 2017 by joe Doe

2 Answers

2

The lines are seperate from each other:

The first line belongs to the line char* a = "AAAA";, saving the value of the variable to RAM.

The second line accesses the variable from RAM for the line printf("%s", a); as the parameter.

Technically, both lines would be optional, as you could have written:

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

EDIT: For skipping this unnecessary code, you could enable automatic optimizations (for GCC: -O2)

answered on Stack Overflow May 31, 2017 by caylee • edited May 31, 2017 by caylee
0

The problem is that your disassembler is broken (or at least "too smart") and "helpfully" giving you different, confusing, information from what one would normally expect. These two lines:

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

should be

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

They access memory in the stack frame indirectly via the rbp register. Such memory is used by the compiler for local variables, thus the "local" in what the disassembler is showing.

answered on Stack Overflow May 31, 2017 by Chris Dodd

User contributions licensed under CC BY-SA 3.0