Search code examples
assemblyx86operating-systemnasm

Why won't pop work inside a function call? (NASM)


I'm trying to pass arguments to a function call by pushing them onto the stack, then popping them into registers inside the function like this:

    push keystring+0x7c00
    call PrintString
    jmp $

;====functions====

PrintString:
    pop ecx
    mov ah, 0x0e
LoopHead:
    mov bl, 0
    mov al, [ecx]
    int 0x10
    inc ecx
    add bl, [ecx]
    jnz LoopHead
    ret

;====variables====

keystring:
    db "Press any key...", 0

;====padding====

    times 510-($-$$) db 0
    db 0x55, 0xAA


It works fine if I do it by storing the argument in ecx and using ecx in the function, but for some reason pop just won't work. Does anybody know how I can fix this?


Solution

  • I figured it out guys, I had to pop it into cx twice. I couldn't of figured it out without y'alls suggestions though, like trying 16 bit addresses, and knowing that the return address gets pushed to the stack automatically. Here's the fixed code if anyone's interested:

        org 0x7c00
        push keystring
        call PrintString
        jmp $
    
    ;====functions====
    
    PrintString:
        pop di
        shl edi, 16
        pop di
        push eax
        push ebx
        push ecx
        xor ecx, ecx
        mov cx, di
        mov ah, 0x0e
    LoopHead:
        mov al, [ecx]
        int 0x10
        inc ecx
        mov bl, [ecx]
        add bl, 0
        jnz LoopHead
        pop ecx
        pop ebx
        pop eax
        shr edi, 16
        push di
        ret
    
    ;====variables====
    
    keystring:
        db "Press any key...", 0
    
    ;====padding====
    
        times 510-($-$$) db 0
        db 0x55, 0xAA