1

I have some problems when accessing data when it is located in

section .data

I wrote a small program in assembler (using NASM) which consists of a bootloader that loads some 'kernel' code. This kernel code is then executed once loaded in memory.

I'll first show the code, then formulate my problem.

The first part of the program consists of initial statements and data definitions:

org 7C00h

jmp _start          

OS_LOCATION             equ     0x7E00
STACKSEG                equ     0xCE00
STACKSIZE               equ     8192

DRIVE_NR                equ     80h
NO_ERROR                equ     0
BOOT_ERROR              equ     1000

PINK                    equ     0dh
YELLOW                  equ     0eh
WHITE                   equ     0fh

letterB                 db      'B'

;=============================================================================
;section .data      ;A PROBLEM OCCURS WHEN I UNCOMMENT THIS LINE (SEE LATER)
letterD                 db      'D'

The 2nd part is the bootloader code:

;=============================================================================
segment .text 

_start:     
    cli
    mov     ax, cs                      
    mov     ds, ax                  ; DS = CS
    mov     es, ax                  ; ES = CS
    mov     ax, STACKSEG            
    mov     ss, ax                  ; SS = STACKSEG
    mov     sp, ax
    add     sp, STACKSIZE
    mov     bp, sp
    sti

    ;-----------------------------------------------------------
    ; Display tests
    ;-----------------------------------------------------------
    mov     ax, 0B800h
    mov     es, ax
    mov     di, (160 * 0) + (2 * 0)     ; Row and Column
    mov     ah, PINK                    ; Attribute byte        
    mov     al, 'A'                 ; load immediate 
    mov     [es:di], ax             ; OK: A IS DISPLAYED

    mov     ax, 0B800h
    mov     es, ax
    mov     di, (160 * 0) + (2 * 1)     ; Row and Column
    mov     ah, PINK                    ; Attribute byte        
    mov     al, byte [letterB]          ; load from memory
    mov     [es:di], ax             ; OK: B IS DISPLAYED

    ;-----------------------------------------------------------
    ; Load OS
    ;-----------------------------------------------------------
    mov     ax, OS_LOCATION
    mov     es, ax
    mov     bx, 0
    push    dword 4                     ; # sectors
    push    dword 2                     ; start sector
    call    loadSector          
    cmp     ax, BOOT_ERROR
    jnz     _startOS

_reboot:
    mov     ah, 0
    int     16h

    db      0x0ea 
    dw      0x0000 
    dw      0xffff 

    ;-----------------------------------------------------------
    ; Start OS
    ;-----------------------------------------------------------
_startOS:
    jmp     OS_LOCATION:0000        ; jump to our os

;***************************************************************************
loadSector:
    push    ebp
    mov     ebp, esp
    pushad

    mov     ah, 2
    mov     al, [ebp+10]            ; # sectors
    mov     ch, 0                   ; track
    mov     cl, [ebp+6]         ; start sector
    mov     dh, 0                   ; head
    mov     dl, DRIVE_NR            ; drive nr  (NOK: 81h, 0h)
    int     0x13
    jc      _err_loadSector

    popad
    mov     ax, NO_ERROR
    jmp     _exit_loadSector

_err_loadSector:
    popad
    mov     ax, BOOT_ERROR

_exit_loadSector:
    mov     esp, ebp
    pop     ebp
    ret     8
;***************************************************************************

times 512d - 2 - ($ - $$)   db      0   ;Zerofill up to 510 bytes

dw 0AA55h                           ;Boot Sector signature

The last part consists of the very simple 'kernel' code (this is to where the bootloader jumps when executing jmp OS_LOCATION:0000)

;-----------------------------------------------------------
; More display tests
;-----------------------------------------------------------
mov     ax, 0B800h
mov     es, ax
mov     di, (160 * 2) + (2 * 0)     ; Row and Column
mov     ah, YELLOW                  ; Attribute byte        
mov     al, 'C'                 ; load immediate
mov     [es:di], ax             ; OK: C IS DISPLAYED

mov     ax, 0B800h
mov     es, ax
mov     di, (160 * 2) + (2 * 1)     ; Row and Column
mov     ah, YELLOW                  ; Attribute byte        
mov     al, byte [letterD]          ; load from memory
mov     [es:di], ax             ; D IS DISPLAYED ONLY IF 'section .data' IS COMMENTED

So far for the code.

Now, the above code works when I define 'letterD' NOT in the data section:

;section .data      ; IT WORKS WHEN THIS LINE IS COMMENTED
letterD     db      'D'

--> The bootloader code displays: AB

--> The kernel code displays: CD

The problem though is when I define 'letterD' in the data section:

section .data       ; IT DOESN'T WORK WHEN THIS LINE IS UNCOMMENTED ???
letterD     db      'D'

--> The bootloader code displays: AB

--> The kernel code displays: C

The letter 'D' is NOT displayed

It is as if the data can not be found when placed in a data section. (FYI: nasm builds my code to BIN-format)

What is going on here? How to solve this?

thank you

Chris

Chris
  • 117
  • 1
  • 5
  • Actually you need to set `DS` to `.data / 16`. Note that for flat binary file and a boot sector it doesn't make much sense to use sections anyway. – Jester Feb 18 '15 at 16:53
  • Is the "last part" part of the same file? If so, the `org 7C00h` will apply to it, also. This will cause Nasm to calculate the address incorrectly. This doesn't explain why it works without `section .data` though... – Frank Kotler Feb 18 '15 at 17:33
  • If I don't use the data section then the amount of data available = size of bootloader - 510 bytes. That's why, by specifying the data section, the data is put after the 'kernel' code, where much more space is available – Chris Feb 18 '15 at 21:47
  • @Jester: wjhat do you mean with " set DS to .data / 16" how is that translated to assembler? thx – Chris Feb 18 '15 at 21:59
  • Defining a data section will not get you any extra space. The BIOS still just loads 1 sector, whatever you put after it will not be in memory unless you load it yourself. Apparently nasm doesn't even support the `SEG` directive for the `bin` format, so you'd need to use another format and a linker. You are just making your life unnecessarily complicated. – Jester Feb 18 '15 at 22:41
  • I think I get it... maybe... Without the `section .data`, the variable remains in your bootloader code, loaded by bios to 7Cxxh. If you put it after your kernel (as you want to), it gets loaded (by your code) to 7E00h:xx. `ds` does not match this (easily fixed) - but the offset calculated by Nasm is still subject to the `org 7C00h` which won't be correct. We would like the kernel code to be `org 0`, but Nasm will allow only one `org`. Possible solutions: assemble "kernel.asm" as a separate file (`org 0`), and combine the two with `cat` or `copy /b` or perhaps `incbin`. Write as usual. – Frank Kotler Feb 18 '15 at 23:30
  • @Jester: " The BIOS still just loads 1 sector, whatever you put after it will not be in memory unless you load it yourself." ... this is being taken care of by loadSector. The BIOS loads the MBR automatically, the following sectors, where the kernel is located on disk, will be loaded by loadSector – Chris Feb 18 '15 at 23:44
  • @Frank: I will try that. hope it'll work. thx – Chris Feb 18 '15 at 23:45

0 Answers0