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
Post a Comment