0

I've seen a lot of questions doing the same thing as me but didn't really find an answer that helped me.

Like the title says, I'm trying to make a simple print function that takes an address of a string that was pushed to the stack and print it.

General criticism of my code is obviously more then welcome.

[bits 16]
[global _start]

org 0x7c00                              ;set origin to smthn idk someone recommanded it

;globals
buffer: db "Hello World!", 0x0a, 0      ;null terminated string
eop: db "End of program", 0

_start:
    xor ax, ax
    mov ds, ax                          ;set data segment to 0

    push buffer
    call print                          ;call print with addr of buffer in the stack

    mov al, 'F'                         ;debug
    mov ah, 0x0e
    int 0x10

    jmp $                               ;end of program (loop forever)

print:
    .prepare:
        push bp
        mov bp, sp

        pusha                           ;save all registers

        mov si, [bp+4]                  ;use si so save index of string     

    .char_loop:
        mov al, [si]                    ;offset from added data
        add si, 1

        cmp al, 0x0                     ;string is terminated by null
        je .return

        mov ah, 0x0e
        int 0x10

        jmp .char_loop

    .return:
        popa
        pop bp
        ret

times 510-($-$$) db 0                   ;fill dead space with 0
db 0x55, 0xaa   

                    ;end boot sector with 0x55 0xaa

Edit: forgot to include the current output-enter image description here

  • 1
    `mov si, [bp-4]` should probably be `mov si, [bp+4]`. There is no point in saving `si` if you already use `pusha/popa`. You also probably don't want to print a null char. You couldn't find an answer that helped you because every question is, of course, slightly different from the others. That's why we require a bit of debugging/effort from the OP or this site will turn into a debugging service. – Margaret Bloom May 20 '21 at 08:48
  • 1
    The ORG directive seems off. It should be `0x7c00` since you are zeroing `ds` (BTW, it's good practice to also set up the stack). It also seems that your data is in the way of CPU execution. – Margaret Bloom May 20 '21 at 09:34
  • Fixed the origin, could you link me to an article that explains how to set up the stack? Also, I don't think I understand what you mean by "It also seems that your data is in the way of CPU execution." Thanks! – Just a Salad Knight May 20 '21 at 10:24
  • 1
    `buffer` is the first item in your program (which will be loaded to address 7C00h). The loader will enter your program at the very first byte, regardless whether you intended this to be used as data or code. So your data will be misinterpreted as code, which can cause problems. – ecm May 20 '21 at 10:57
  • seems that moving the global variables to the end did fixed it, thank you so much! – Just a Salad Knight May 20 '21 at 12:05
  • "Data is in the way of CPU execution" means that the CPU can't tell the difference between data and instructions. If you have something like `mov ax,bx` followed directly by `db "Hello World",0` then the CPU will read your string as though it were instructions to execute and then do who knows what. That's why moving your global variables to the end fixed it. They weren't "seen" by the `ip` register. – puppydrum64 Dec 20 '22 at 16:55

0 Answers0