1

So, for this assignment I have to write an Assembly "function" to be called by C code. The purpose of the function is, given an integer and a memory address (the address of a char array, to be used as a string), convert the integer to a string, which starting address is the memory address that is given. I'm on Ubuntu Linux, btw.

Here's the Assembly code (I tried to make it using the Linux x86_64 ABI calling conventions)(It is in AT&T syntax):

.global dec
.type dec, @function
.text
dec:

######################### Subroutine prologue

push    %rbp            # Save the base pointer
movq    %rsp, %rbp      # Make the stack pointer the new base pointer
push    %rdi            # Stack parameter 1
push    %rsi            # Stack parameter 2

push    %rbx            # Save callee-saved registers
push    %r12
push    %r13
push    %r14
push    %r15


######################### Subroutine body

movq    %rdi, %rax
xor     %rcx, %rcx
addDigit:
cmp     $0, %rax
je      putMem
xor     %rdx, %rdx
mov     $10, %ebx
div     %ebx
addq    $'0', %rdx
pushq   %rdx
inc     %rcx
jmp     addDigit

putMem:
cmp     $0, %rcx
je      endProg
popq    (%rsi)
add     $1, %rsi
dec     %rcx
jmp     putMem

endProg:
movq    $0x0, (%rsi)
movq    -16(%rbp), %rsi
mov     $1, %rax

######################### Subroutine epilogue

popq %r15          # Restore callee-saved registers
popq %r14
popq %r13
popq %r12
popq %rbx

movq %rbp, %rsp    # Reset stack to base pointer.
popq %rbp          # Restore the old base pointer

ret                # Return to caller

And here is my C code:

extern int dec(int num, char* c);
#include <stdio.h>
int main(){
    char* a = "Test\n";
    dec(0x100, a);
    printf("Num: %s\n", a);
}

It compiles without any problems, but when I try to run, it segfaults. I've tried debugging it with gdb, and apparently the problem occurs when I try to run the instruction

pop     (%rsi)

So, I made a few changes in my C code:

extern int dec(int num, char* c);
#include <stdio.h>
int main(){
    char c;
    dec(0x100, &c);
    printf("Num: %s\n", &c);
}

Now, when I attempt to run it, I get this message:

Num: 256
*** stack smashing detected ***: ./teste.out terminated
Aborted (core dumped)

Can someone help me understand what's going on here and how do I fix my code? Thanks in advance.

  • 1
    This works: Change `char c;` to `char c[] = "Test\n";` and `dec(0x100, &c);` to `dec(0x100, (char*)c);`. – rkhb Oct 16 '18 at 17:52
  • Same result here, pal. `Num: 256 *** stack smashing detected ***: ./teste.out terminated Aborted (core dumped)` – João Pedro Lukasavicus Silva Oct 16 '18 at 17:57
  • 1
    It works on my Debian Jessie, GCC 4.9.2. So, I'm sorry, I can't help. – rkhb Oct 16 '18 at 18:06
  • 1
    `popq (%rsi)` and `movq $0x0, (%rsi)` store **8** bytes at once onto the stack. Try to enlarge the string array: `char c[] = "TestTestTest\n";` – rkhb Oct 16 '18 at 18:40
  • Your `pop`s don't seem to match your `push`es. You push `%rbp, %rdi, %rsi, %rbx, %r12, %r13, %r14, %r15`, but then pop `%r15, %r14, %r13, %r12, %rbx, %rbp`. There are a few missing... – David Wohlferd Oct 16 '18 at 22:43
  • @DavidWohlferd true but `rsp` is restored properly from `rbp` and `rsi` is loaded with the obscure `movq -16(%rbp), %rsi`. Of course `rsi` and `rdi` don't need to be preserved so those pushes could be removed. – Jester Oct 16 '18 at 23:51

0 Answers0