1

I've been trying to get it to work for several hours now and nothing seems to make the output to come out in either one or two lines. I've taken the second loop I had before with a string, changed a's to b's and even switched the order little by little.

Code:

[org 0x7c00]
mov ah, 0x0e
mov bx, varName

printString:
    mov al, [bx]
    cmp al, 0
    je end
    int 0x10
    inc bx
    jmp printString
end:
    jmp $

varName:
    db "Hello World", 0


mov bh, 0x0e
mov bl, 'Z'
int 0x10

loop:
    dec bl
    cmp bl, 'A' - 1
    je exit
    int 0x10
    jmp loop
exit:
    jmp $


times 510-($-$$) db 0
dw 0xaa55

current output: Hello World

I tried removing both, one at a time, and it works as intended ran separately.

Note: I'm using qemu, asm, vim and have been using vscode to help with any writing misspellings

  • 1
    What does `jmp $` do? (where does it jump to). – 500 - Internal Server Error Oct 06 '21 at 19:44
  • @500-InternalServerError: It's an infinite loop, jumping to the start of this source line. That's what `$` means in NASM syntax. It's standard for bootloaders, since there's nothing to exit to. (Although it's best to put a `hlt` inside the loop to save a bit of power.) – Peter Cordes Oct 06 '21 at 20:04
  • @500-InternalServerError ```jmp $``` supposedly goes to the current address, but I'm not sure what that's supposed to be, since removing any of them didn't do anything to help with the problem. – PurpleDDive Oct 06 '21 at 20:07
  • 3
    @500-InternalServerError: Oh, now I understand; that was a rhetorical question. There are two `jmp $` lines in this program, and execution will never leave whichever one is encountered first. (But if you *just* take out the first one without other changes, then execution will fall into the ASCII data. [Assembly (x86): db 'string',0 does not get executed unless there's a jump instruction](https://stackoverflow.com/q/30561366)). So yeah, the caught-in-inf-loop problem would be trivially discovered by **single-stepping with a debugger**, e.g. Bochs, or GDB-remote to QEMU. – Peter Cordes Oct 06 '21 at 20:10

1 Answers1

2

changed a's to b's

Don't do this! If an api states that it expects the function number in the AH register, then it will surely not help to try passing it in the BH register.

In a sense you got lucky with that jmp $ not letting you execute that bogus second part.


To execute both parts of the code, you could replace that jmp $ (which is an endless loop), with a normal jump to the first instruction of the second part:

    ...
end:
    jmp Part2

varName:
    db "Hello World", 0

Part2:
    mov ah, 0x0E   ; BIOS.Teletype
    mov al, 'Z'
    ...

Alternatively, move the data to below the second part. That way no jump is needed:

    ...
end:
    mov ah, 0x0E   ; BIOS.Teletype
    mov al, 'Z'
    ...
varName:
    db "Hello World", 0
    ...

Since this is a bootsector program you might take a look at Disk Read Error while loading sectors into memory where I have listed some things that are important in bootsector programs and that your current program is still missing. e.g. You don't setup any segment registers and you are omiting the DisplayPage parameter for the BIOS.Teletype function.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76