0

I am creating a simple function that prints a character to the screen

STD_OUTPUT_HANDLE   equ -11
NULL                equ 0

global Start
extern ExitProcess, GetStdHandle, WriteConsoleA

section .bss
msg     resb    1



section .text

Start:
    push 'b'
    call Print




Print:
    ; Function Start
    push    ebp 
    mov     ebp,esp
    
    ; accepting the argument 
    mov     ebx , [esp + 8]
    mov     [msg],ebx
    
    ; eax = handle
    push    STD_OUTPUT_HANDLE
    call    GetStdHandle
    
    ; WriteConsoleA System call 
    push    NULL
    push    1
    push    msg
    push    eax
    call    WriteConsoleA 
    
    
    ; Funcion end
    mov     esp, ebp
    pop     ebp
    ret

When I remove the ret instruction the output is as expected is b but when I add it back the output changes to b., what's Happening ????

I am using the Nasm Assembler and the golink link

  • 1
    Your `Start` falls through (continues into) `Print` because you did not exit the program. PS: learn to use a debugger. – Jester Feb 09 '23 at 14:42
  • but it works fine when I remove the ret instruction ?? – Djebbar Abderrahmene Feb 09 '23 at 14:49
  • 3
    If you remove the `ret` behind `; Function end` your program crashes without re-entering the function. Instead after `call Print` add a system or library call to end the program's run. BTW, you shouldn't read and write a 32-bit register for the data, use `movzx ebx, byte [esp + 8]` and `mov byte [msg], bl`. – ecm Feb 09 '23 at 14:51
  • @ecm but why does the program re-enter the function shouldn't it execute the next instruction. – Djebbar Abderrahmene Feb 09 '23 at 14:57
  • Yes, it should. Then, tell me what is "the next instruction" if you look at this stretch of your code: `call Print` \ \ \ \ `Print:` \ `; Function Start` \ `push ebp` ? – ecm Feb 09 '23 at 15:19
  • @ecm `mov ebp,ecp` right ? – Djebbar Abderrahmene Feb 09 '23 at 15:28
  • 1
    `esp` but yes. What I mean is after your `call` though. There is no separation or termination of the code control flow path here. When the `retn` runs it will branch back to after the `call`. What is after the `call`? The function's code, which will execute next (a second time). – ecm Feb 09 '23 at 15:35
  • 2
    Use a debugger to single-step through your code and follow the path of execution. This should make it obvious what's happening, especially if you look at disassembly so you can see that the machine code is just contiguous. – Peter Cordes Feb 09 '23 at 21:18
  • 1
    See the linked duplicates. Your `Start` is like a function that's called by Windows DLLs or CRT startup code; without a `ret` there, execution falls through into `Print` again, as ecm explained. – Peter Cordes Feb 10 '23 at 04:33

0 Answers0