Search code examples
assemblyx86nasmbootloader16-bit

x86 assembly: Understanding db syntax


I've just started learning x86 assembly by following along with a online book that I found: http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf

As I was going through the book and following the examples, I ran into a problem that I couldn't solve due to my own ignorance of assembly, or maybe programming in general. I was trying to build some code in my boot sector program that could print a null-terminated string but the program only prints the first character.

Here is some example code that I was trying to run:

[org 0x7c00]
    mov bx, Hello
    mov ah, 0x0e
Keep_Printing:
    mov al, [bx]
    cmp al, 0
    je Finished_Printing
    int 0x10
    add bx, 0x0008
    jmp Keep_Printing
Finished_Printing:

    cli
    hlt

Hello:
    db "Hello", 0

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

I was thinking what would happen is that bx would contain the memory address of the first two letters of Hello, but I wasn't sure what would happen when I tried to move the contents of that 16 bit register into the 8 bits of al. When I run it, it only prints 'H' so I guess the top 8 bits goes into al, and the rest get ignored?

After that, I was wanting the program to keep checking al to see if it was 0 as it looped through the string, printing to the screen if it wasn't 0. I wasn't really sure how to iterate through a string character by character in assembly, but I thought since I had the starting address of Hello, I could just keep adding 8 bits to the memory address in bx. What prints changes based on whatever I'm hitting in memory after the 'H', but I'm not sure why it wouldn't be the rest of the string.

I'm sure I'm misunderstanding all kinds of things on all kinds of levels, but hopefully someone here can help clear things up. Thanks!


Solution

  • Memory is addressed in bytes, not bits, so you need to add 1 byte, not 8 bits. As you have it, adding 8 to BX will address the memory 8 bytes above the H, which will be a 0 byte (since you specify times 510-($-$$) db 0 (iow, fill up to byte 510 with 0 bytes.

    Solution : add 1 to BX, not 8 (probably better accomplished with INC BX - faster and shorter).

    btw: mov al,[bx] means 'move the BYTE pointed to by BX (ie at the address contained in register BX) to AL`

    db means define BYTE, not bit