首页 > 解决方案 > 我的代码行中的“hello world”有什么问题?

问题描述

我试图在 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 

qemu的图片应该在这里

标签: assemblynasmx86-16bootloaderbios

解决方案


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

我可以建议尝试这段代码吗?我已经包含了注释和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...

这是受人尊敬的结果:

'Hello, World!' 的输出


推荐阅读