Your decstru funcion is pushing lots of values on stack and not poping enough.
And it is still wrong. You should pay attention to details instead of copying someone else's code.
The algorithm should be:
; p = pointer to the end of buffer;
; c = counter
; q = quotient;
; r = remainder;
p = buffer + sizeofbuffer - 1;
c = 0;
do { q = n / 10; r = n % 10; n = q; *p-- = r + '0'; c++; } while ( q != 0 );
return ++p, c;
A modified examlpe (with many corrections) to your code:
;------------------------------------------------------------------------
; sum.asm
;
; Compile: nasm -f elf64 sum.asm -o sum.o
; ld -s -o sum sum.o
;
; It is garanteed initializing E?? portion of R?? will zero
; the upper 32 bits, so using 'mov eax,1' is *shorter* than
; 'mov rax,1' and has the same effect.
;
; Using LEA instead of MOV to load pointers is my preference.
; There is nothing wrong using MOV.
;-------------------------------------------------------------------------
section .data
; If you intend to read two QWORDs, these must be declares as QWORDs,
; not DWORDs.
num1: dq 654321
num2: dq 123456
section .rodata
lf: db `\n`
lf_len equ ($ - lf)
section .text
global _start
_start:
mov rax,[num1] ; Reading QWORDs, see?
add rax,[num2]
call printulong
mov eax,1
mov edi,eax
lea rsi,[lf]
mov edx,lf_len
syscall
mov eax,60
xor edi,edi
syscall
;---------------------------
; printulong
; Print unsigned long int in decimal.
;---------------------------
; Entry: RAX: unsigned long int to convert
; Destroys: RAX,RBX, RCX, RDX and RSI
; Unless you save and restore them.
;---------------------------
align 4
printulong:
; push rax ; Don't need to save them
; push rbx ; for this code.
; push rcx
; push rsi
; push rsi
sub rsp,32 ; Allocate space for buffer on stack.
; I could allocate only 20 bytes, but the stack
; pointer must be aligned by 8.
;
; Why 20 bytes? The maximum decimal value for
; an unsigned QWORD is "18446744073709551615".
lea rsi,[rsp+24] ; Points to the end of the buffer.
xor ecx,ecx ; counter = 0.
mov ebx,10 ; divisor.
align 4
.loop:
xor edx,edx
div rbx
add dl,'0' ; add '0' to the remainder, not the quotient!
mov [rsi],dl ; store it on the buffer.
inc ecx ; we have one more char there.
dec rsi ; points to 'next' position.
test rax,rax ; quotient == 0?
jnz .loop ; no, loop.
inc rsi ; points to the begining of the buffer.
mov eax,1 ; sys_write
mov edi,eax ; stdout
mov edx,ecx ; string size.
syscall
add rsp,32 ; Reclaim allocated space.
; pop rsi ; Don't need to restore them
; pop rdx ; for this code.
; pop rcx
; pop rbx
; pop rax
ret