Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does NASM's resb do in binary output format?

I saw a piece of NASM code that uses resb. However, this code runs in a real mode operating system, and the output format is flat binary. NASM doesn't give an error when doing this, but after dissecting the output file, I still couldn't find what actually happens.

bits 16
org 0x8000

start:
    mov ax, msg
    call os_input_string
    mov si, msg
    call os_print_string
    ret

section .bss
msg: resb 256

Here are a few possibilities that I've thought of:

  • resb simply allocates some unused space at the end of the binary
  • it doesn't really work at all, and stuff blows up.
like image 766
sadljkfhalskdjfh Avatar asked Nov 21 '25 06:11

sadljkfhalskdjfh


1 Answers

When NASM generates a binary -f bin it follows some basic rules about the sections. The NASM manual says this:

7.1.3 Multisection Support for the bin Format

[snip]

  • The .bss section will be placed after the last progbits section, unless start=, vstart=, follows=, or vfollows= has been specified.

progbits is a flag that denotes a section will physically appear in the file (the default for .text and .data sections). .bss defaults to nobits which means the data reserved in this section doesn't physically appear in the file, but any addresses of labels in a nobits flagged section will resolve (by default) to the memory just past the last progbits (.text and .data etc) section. The BSS area in a binary file is not initialized to zero. It will be whatever happens to be in memory, so consider the area to contain garbage. If you need a binary program to initialize this area to zero, you will have to do it yourself once your program starts executing.

There are hints in your question that you are creating the second stage of a bootloader. I'm going to provide an example of code that will initialize the BSS area with zeros. This code assumes that the second stage was loaded at 0x0000:0x8000 :

bits 16
org 0x8000

section .text
start:
    ; Initialize the entire BSS area to zero
    ; Assume we are the second stage of a bootloader at 0x0000:0x8000
    mov cx, _bss_end-_bss_start    ; Length of region in CX
    xor ax, ax                     ; AX=0 (also used for rep stos)
    mov es, ax
    mov ds, ax                     ; DS=ES=0x0000
    mov di, _bss_start             ; Offset of BSS region 
    rep stosb                      ; Set CX bytes of data at ES:[DI] to AL(0)

    mov ax, msg
    mov si, msg2

    ; Put second stage in halt state indefinitely.
    cli
.endloop:
    hlt
    jmp .endloop

section .bss
_bss_start:      ; Label for start of BSS
msg: resb 256
msg2: resb 10
_bss_end:        ; Label at end of BSS

Although the memory for BSS is not part of the binary file on disk, the labels for data in this area resolve to real offsets. You can tag the beginning and end of the BSS area, and in this case I use _bss_start and _bss_end. These labels are used to determine the extent of the BSS area so that it can be initialized to zero when our code begins to execute.

like image 147
Michael Petch Avatar answered Nov 24 '25 05:11

Michael Petch



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!