#For the assembly sages

12 messages · Page 1 of 1 (latest)

prisma kestrel
#

for the assembly sages here can you point out something im missing here... I've been wanting to pickup x86 assem, and in the compilation of the following C code, I've run into something I don't understand.

Looking at the C code; a function inside the main function is using mains parameters. Not really interested in what it does, but looking at the corresponding assembly (unoptimized compilation btw) we have standard prologue and a 16 byte allocation onto the stack, cool, we have 2 params this is x64 assem makes sense since the memory addresses of the params are 8bytes respectively.

I don't get the offsets chosen by the compiler, shouldn't the first&second move instruction be:
"mov DWORD PTR [rbp], edi";
"mov DWORD PTR -8[rbp], edi";

Wouldn't the second ptr be exceeding the stack frame? Sorry for the lengthy post, and thanks for your help.

pliant havenBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.

thick patio
#

It depends on the calling convention
mov DWORD PTR [rbp], edi would load 4 bytes from your current stack pointer into edi

Really you can look at it like this:

; not actual syntax 
push arg_v ; 8 bytes <--------------------------|
push arg_c ; 4 bytes <------------------------| |
                                              | |
main:                                         | |
        push    rbp                           | |
        mov     rbp, rsp                      | |
        sub     rsp, 16                       | |
        mov     DWORD PTR [rbp-4], edi  ------| |
        mov     QWORD PTR [rbp-16], rsi --------|
        mov     rdx, QWORD PTR [rbp-16]
        mov     eax, DWORD PTR [rbp-4]
        mov     rsi, rdx
        mov     edi, eax
        call    x(int, char**)
        nop
        leave
        ret
#

I between the arg_v and arg_c it is then pack with another 4 bytes

prisma kestrel
thick patio
#

You can see it change if you use different variables too and not main

#

;asm -O0

int x(char** argv, int& argc);

int t( char** argv, int& argc)
{
    return x(argv, argc);
}
vast eagleBOT
#
Assembly Output
t(char**, int&):
  push rbp
  mov rbp, rsp
  sub rsp, 16
  mov QWORD PTR [rbp-8], rdi
  mov QWORD PTR [rbp-16], rsi
  mov rdx, QWORD PTR [rbp-16]
  mov rax, QWORD PTR [rbp-8]
  mov rsi, rdx
  mov rdi, rax
  call x(char**, int&)
  leave
  ret

thick patio
#

;asm -O0```cpp
int x(char** argv, int argc);

int t( char** argv, int argc)
{
return x(argv, argc);
}

vast eagleBOT
#
Assembly Output
t(char**, int):
  push rbp
  mov rbp, rsp
  sub rsp, 16
  mov QWORD PTR [rbp-8], rdi
  mov DWORD PTR [rbp-12], esi
  mov edx, DWORD PTR [rbp-12]
  mov rax, QWORD PTR [rbp-8]
  mov esi, edx
  mov rdi, rax
  call x(char**, int)
  leave
  ret

pliant havenBOT
#

@prisma kestrel Has your question been resolved? If so, run !solved :)

prisma kestrel
#

!solved