【问题标题】:What is wrong with my "hello world" in the lines of code?我的代码行中的“hello world”有什么问题?
【发布时间】:2019-09-19 19:06:50
【问题描述】:

我试图在 Qemu 中加载一个“Hello World”字符串,但它只显示一个字母“H”。我对此很陌生,在此先感谢您尝试帮助我:D 我在 Windows 操作系统上执行此操作。


[BITS 16]
[ORG 0X7C00]

MOV SI, BOOTLOADSTR
CALL Printstring
JMP $

Printcharacter:
MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x07

INT 0x10
RET

Printstring
next_character:
MOV AL, [SI]
INC SI
OR AL, AL
JZ exit_function
CALL Printcharacter
exit_function
RET

;DATA
BOOTLOADSTR db 'Hello World', 0

TIMES 510 - ($ - $$) DB 0
DW 0XAA55 

The image of the qemu should be here

【问题讨论】:

  • CALL Printcharacter 之后我看不到您返回并处理下一个字符。好像你错过了 jmp next_character 所以它只处理字符串中的第一个字母并退出。
  • 为了使您的引导加载程序代码更加健壮,您应该将 DS 设置为 0(在开始时),因为您使用 org 07c00 您可以使用 xor ax, ax mov ds, ax 来做到这一点。
  • @MichaelPetch:标签使用问题:[bootloader] 是否适合 实际上从磁盘加载更多代码的独立事物?当我昨天重新标记这个时,我把它忽略了,因为我不确定它是否适用于像这样作为 MBR 引导扇区加载的代码。但可能这对标签来说更有用,因为它描述了代码运行的环境,而不是它的目的。也许标签使用弹出窗口可以使用编辑来澄清。
  • @PeterCordes:从技术上讲,它仍然是一个引导加载程序,将这些问题放在一个标签下是有意义的,因为这些问题通常与加载/不加载多个代码的特定问题有关部门会遇到。这种代码也有可能演变成以后加载扇区的东西。
  • @PeterCordes :我可以妥协并称它为“bootsector”而不是“bootloader”。那就无所谓了。但是标签一直存在。

标签: assembly nasm x86-16 bootloader bios


【解决方案1】:

您的代码似乎错误地引用了 [DS:SI]...看来您只是从 [DS:SI] 中获取一个字节尝试使用 lodsb 连续收集字节直到 NULL 终止 [CHAR_STREAM] [0x00]

我可以建议尝试这段代码吗?我已经包含了 cmets 和 lodsb 指令以及简单的细节来解释这个过程:

[bits   16]                             ; Declare CPU Instructions as [REAL_MODE]
[org    0x0000]                         ; Organize Memory to Start @ [0x0000]
                                        ; We'll Manually setup Memory Organization Later...

jmp _glEntry                            ; Relocate to Function:

output16_char_array:                    ; Legacy BIOS Output ChAR_STREAM Function
    xor ax, ax                          ; Zero [AX] Register
    mov ah, 0x0E                        ; Assign [0x0E] to [AX] : (Legacy BIOS Function Code for BIOS Display)
                                        ; Continue Code Execution:
    .output16_char_array_loop:
        lodsb                           ; Collect Single Byte from [DS:SI] and increment SI by 1 : ([AL] = [DS:SI]; inc [SI])
        or  al, al                      ; Check Whether [AL] is [0x00]
        jz  .output16_char_array_done   ; [AL] == [0x00] Proceed to Function:
        int 0x10                        ; [AL] != [0x00] Continue to Display Hex->ASCII [CHAR]
        jmp .output16_char_array_loop   ; Relocate [CS] to create an Infinite Loop...

    .output16_char_array_done:
        ret                             ; Return to Calling [CS] Memory Position...



WELCOME_MSG db  "Hello, World!",    0x0D,   0x0A,   0x00



_glEntry:
    cli                                 ; Disable CPU Interrupts
    xor ax, ax                          ; Zero [AX] Register
    mov ax, 0x07E0                      ; Assign [0x07E0] to [AX] : (0x07E0)
    mov ss, ax                          ; Assign [AX] to [SS] : ([AX]*[0x0010]) : (0x7E00)
    mov sp, 0x1000                      ; Assign [0x1000] to [SP] : (0x1000) ([0x07E0]:[0x1000])
    sti                                 ; Enable CPU Interrupts
                                        ; Continue Code Execution:
    xor ax, ax                          ; Zero [AX] Register
    mov ax, 0x07C0                      ; Assign [0x07C0] to [AX] : (0x07C0)
    mov ds, ax                          ; Assign [AX] to [DS] : ([AX]*[0x0010]) : (0x7C00)
                                        ; Continue Code Execution:
    mov si, WELCOME_MSG                 ; Assign [WELCOME_MSG] to [SI] : (0x[....])
    call    output16_char_array         ; Call our Output [CHAR_STREAM] Function
                                        ; Continue Code Execution on Return:
    xor ax, ax                          ; Zero [AX] Register
    int 0x16                            ; Call BIOS Await Keystroke Interrupt
    xor ax, ax                          ; Zero [AX] Register
    int 0x19                            ; Call BIOS Reboot Interrupt
                                        ; Continue Code Execution if interrupts fail...
    cli                                 ; Disable CPU Interrupts
    hlt                                 ; Halt CPU Execution:



times   510 - ( $ - $$ )    db  0x00        ; Pad [BOOTSECTOR] with [0x00] up to 510 Bytes...
dw  0xAA55                      ; Assign [MAGIC_MBR] Value...

这是受人尊敬的结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    相关资源
    最近更新 更多