So I recently moved to nasm again and tried to build some basic stuff (putc and puts).
Putc
works fine but the problem is that after I call putc
in puts
, the ret
in putc
does not return to the ip
pushed onto the stack by puts
and so no more instructions are being executed in puts
(debugged that part in gdb).
msg db "Welcome!", 0ah, 0dh, 0h
putc:
push ebp
mov esp, ebp
mov ah, 0ah
; al is set before
mov bh, 0
mov bl, 0
mov cx, 1
int 10h
ret
puts:
push ebp
mov esp, ebp
mov ebx, msg
dec ebx
puts_l:
inc ebx
mov al, [ebx]
call putc
cmp al, 0h
jne puts_l
ret
It's clearly not the best but I think I have a misunderstanding somewhere. I could imagine that a register would be overwritten by putc but that doesn't clarify why the ret
in putc does not return to puts
I should also mention as well that I'm working with x86.
CodePudding user response:
When you do
push ebp
mov esp, ebp
esp
does not point to the pushed ebp
and to the return address any longer, that's the problem which cannot be solved by using LEAVE in the function epilogue. BTW LEAVE
should be paired with ENTER.
If you really need the stack frame (e.g. to define a local memory variable), the skeleton might look like this:
Function:
PUSH EBP
MOV EBP,ESP
SUB ESP,4 ; The local variable is now addressable as [ESP] alias [EBP-4].
; Here is the Function body which can use local variable(s).
MOV ESP,EBP ; Discard local variable, ESP will point to the saved EBP.
POP EBP ; Restore EBP which might be used as parent's frame pointer.
RET
As your program does not use local variables, it could be
mov esi, msg ; Address of the ASCIIZ string.
call puts
jmp $ ; Program ends here.
puts: ; Function which displays ASCIIZ string at ESI.
lodsb ; Load AL from [DS:ESI], increment ESI.
cmp al, 0h
je puts_2
call putc ; Display a nonzero character in AL.
jmp puts
puts_2: ret
putc: ; Function which displays a character in AL.
mov ah, 0ah ; WRITE CHARACTER.
mov bh, 0 ; Videopage 0.
mov bl, 0 ; Colour in graphic mode.
mov cx, 1 ; Number of times to write character
int 10h ; Invoke BIOS videofunction.
ret
msg db "Welcome!", 0ah, 0dh, 0h ; The displayed ASCIIZ string.