Home > database >  nasm can't call function in function
nasm can't call function in function

Time:12-11

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.
  • Related