assembly - NASM的resb以二进制输出格式做什么?

标签 assembly x86 nasm x86-16

我看到一段使用resb的NASM代码。但是,此代码在实模式操作系统中运行,并且输出格式是平面二进制。 NASM 在执行此操作时不会给出错误,但在剖析输出文件后,我仍然找不到实际发生的情况。

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

以下是我想到的几种可能性:

  • resb 只是在二进制文件末尾分配一些未使用的空间
  • 它根本不起作用,而且东西会爆炸。

最佳答案

NASM生成二进制-f bin时,它遵循有关各部分的一些基本规则。 NASM manual说的是:

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 是一个标志,表示某个部分将实际出现在文件中(.text.data 部分的默认值)。 .bss 默认为 nobits,这意味着本节中保留的数据实际上并不出现在文件中,而是出现在 nobits 中的任何标签地址> 标记的部分将解析(默认情况下)到刚刚过去的最后一个 progbits (.text.data 等)部分的内存。二进制文件中的BSS区域未初始化为零。它将是内存中发生的任何内容,因此请考虑包含垃圾的区域。如果您需要一个二进制程序将该区域初始化为零,则必须在程序开始执行后自己执行此操作。

您的问题暗示您正在创建引导加载程序的第二阶段。我将提供一个代码示例,该代码将用零初始化 BSS 区域。此代码假设第二阶段加载于 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

虽然BSS的内存不是磁盘上二进制文件的一部分,但该区域中数据的标签解析为实际偏移量。您可以标记 BSS 区域的开头和结尾,在本例中,我使用 _bss_start_bss_end。这些标签用于确定BSS区域的范围,以便在我们的代码开始执行时将其初始化为零。

关于assembly - NASM的resb以二进制输出格式做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34268699/

相关文章:

assembly - 为什么 clang 的结尾使用 `add $N, %rsp` 而不是 `mov %rbp, %rsp` 来恢复 `%rsp` ?

c - 我的自定义操作系统内核中的 VGA 显示问题

c - Linux 模块拒绝对 BIOS 的写入权限?

Gcc内联汇编: what's wrong with the dynamic allocated register `r` in input operand?

linux - NASM 通知发送?

assembly - Retq指令,从哪里返回

assembly - DCPU-16 DIV 指令

code-generation - x86指令编码表

performance - 在 x86_64 汇编程序 (yasm) 中使用 POSIX 线程库需要更多的执行时间

linux - 使用汇编在 Linux 终端中清除屏幕?