assembly - Understanding C disassembled call -


i want learn c calling convention. wrote following code:

#include <stdio.h> #include <stdlib.h>  struct tststruct {     void *sp;     int k;  };  void my_func(struct tststruct*);  typedef struct tststruct strc;  int main() {     char a;     = 'b';     strc* t1 = (strc*) malloc(sizeof(strc));     t1 -> sp = &a;     t1 -> k = 40;      my_func(t1);     return 0;    }  void my_func(strc* s1) {         void* n = s1 -> sp + 121;         int d = s1 -> k + 323; } 

then used gcc following command:

gcc -s test3.c 

and came assembly. won't show whole code got rather paste code function my_func. this:

my_func: .lfb1: .cfi_startproc pushq   %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq    %rsp, %rbp .cfi_def_cfa_register 6 movq    %rdi, -24(%rbp) movq    -24(%rbp), %rax movq    (%rax), %rax addq    $121, %rax movq    %rax, -16(%rbp) movq    -24(%rbp), %rax movl    8(%rax), %eax addl    $323, %eax movl    %eax, -4(%rbp) popq    %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc 

as far understood, happens: first callers base pointer pushed stack , stack pointer made new base pointer set stack new function. rest don't understand. far know, arguments (or pointer argument) stored in stack. if purpose of second instruction,

movq        -24(%rbp), %rax 

here, content of %rax register moved address 24 bytes away address in register %rbp. in %rax???? nothing stored there??? think i'm confused. please understand how function works. in advance!

you confuse at&t syntax intel syntax.

 movq -24(%rbp), %rax 

in intel syntax be

 mov rax,[rbp-24] 

so moves data addressed rbp rax, , not vice versa. order of operands src, dest in at&t syntax, whereas in intel syntax dest, src.

then, rid of gas directives make disassembly easier read, assembled code gcc gcc test3.c , disassembled ndisasm -b 64 a.out. note disassembly of my_func function produced ndisasm below in intel syntax:

 000005ef  55                push rbp 000005f0  4889e5            mov rbp,rsp        ; create stack frame. 000005f3  48897de8          mov [rbp-0x18],rdi ; s1 local variable. 000005f7  488b45e8          mov rax,[rbp-0x18] ; rax = s1 (it's pointer) 000005fb  488b00            mov rax,[rax]      ; dereference rax, store rax. 000005fe  4883c079          add rax,byte +0x79 ; rax = rax + 121 00000602  488945f8          mov [rbp-0x8],rax  ; void* n = s1 -> sp + 121 00000606  488b45e8          mov rax,[rbp-0x18] ; rax = pointer s1 0000060a  8b4008            mov eax,[rax+0x8]  ; dereference rax+8, store eax. 0000060d  0543010000        add eax,0x143      ; eax = eax + 323 00000612  8945f4            mov [rbp-0xc],eax  ; int d = s1 -> k + 323 00000615  5d                pop rbp 00000616  c3                ret 

for information on linux x86-64 calling convention (system v abi), see answers what calling conventions unix & linux system calls on x86-64 .


Comments

Popular posts from this blog

node.js - Bad Request - node js ajax post -

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -