1

I am following the book Writing a Simple Operating System — from Scratch by Nick Blundell. I am trying to do the task on the page 21. I wrote a simple program to test how initialized data would work in bin files. Here is the program:

hello.asm

section .data

test:   db      'A'

section .text


        mov     ah,0x0e
        mov     al,[test]
        int     0x10

        jmp     $


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

then to compile I do this:

nasm hello.asm -f bin -o hello.bin

to run:

qemu-system-i386 hello.bin

The problem is, the output expected is the character 'A' but what I got is the character 'S'

The output:

enter image description here

I guess that the label test is not working properly, but I don't know why

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • You'll want to combine your data and text section into one. So put your data in the text section after the code (but before the boot sector signature). If you don't do this your code section will be in the first 512 bytes and the data will start at byte 513 which is not what you want. As well you need to specify a proper origin point (ie: `org 0x7c00`) since you are writing a bootloader. You'll also want to set the _DS_ register to zero at the beginning. – Michael Petch Mar 14 '16 at 09:00
  • 1
    Thank you, it works, and i didn't need to set the DS register to zero – gabriel80546 Mar 14 '16 at 09:17
  • It works because in many environments _DS_ is often 0 before executing your boot loader. This isn't guaranteed, so it is a good idea to do it explicitly. That can be done with code like `xor ax, ax` `mov ds, ax` . The `xor ax, ax` is an efficient way to to set a register (in this case _AX_) to 0. – Michael Petch Mar 14 '16 at 09:27
  • yeah it's a very clever idea to do that, thank you again – gabriel80546 Mar 14 '16 at 09:33

1 Answers1

0

When using NASM with the -f bin option, the .text section will appear in the flat binary file before the .data section. Because of this, if you compile your code the first 512 bytes would contain the code (.text) segment and the data would appear after the first 512 bytes. You want your data in the first 512 bytes when using it in a bootloader like this. With -f bin and bootloaders the best thing to do is remove the .data section and place the data after the code but before the bootloader signature.

You should also set an origin point with the ORG directive. Bootloaders are loaded into memory at physical address 0x07c00 or a CS:IP of 0x0000:0x7c00 (or other equivalent segment offset pairs). The simplest way is to use org 0x7c00at the top of your code. This will generate offsets and labels relative to 0x7c00. The default for NASM using the -f bin option is to use an origin point of 0x0000.

If you use org 0x7c00 you'll need to use a DS segment register value of zero to properly access the data in memory.

Your code could have looked like this:

org 0x7c00

section .text

        xor     ax,ax
        mov     ds,ax      ; DS = AX = 0
        mov     ah,0x0e
        mov     al,[test]
        int     0x10

        jmp     $

test:   db      'A'

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

It is generally a good idea to set up a stack as well. I have a Stackoverflow answer with some general bootloader tips that may be useful.

Community
  • 1
  • 1
Michael Petch
  • 46,082
  • 8
  • 107
  • 198