一个微小的代码启动加载器失败

时间:2017-05-18 04:29:51

标签: assembly x86 nasm bootloader usb-drive

下面的这个小代码是一个用汇编语言编写的引导加载程序,并与Netwide汇编程序(NASM)组装在一起,产生512字节的二进制输出(机器代码)。然后将其复制到可引导设备的第一个扇区然后启动

由于这是一个引导加载程序,它在x86实模式下运行,该模式为16位。

如果你已经完成了代码,你知道它所做的就是逐个打印字符,范围从az,AZ,1-9,0,最后是一个点(。),使用BIOS视频中断10 hex in teletype模式。

因此预计将打印以下内容 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890。

然而不知何故神奇地它缺少字符c,d,e,f和k导致
ab fghij lmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890。

我真的无法弄清楚我哪里出错了,这也适用于emu8086。那么是什么让这个代码在真机上失败了。

感谢您花时间阅读本文。

    ; This code after assembling will be 512 bytes in size and is loaded into the first sector of a bootable device.
    ; while booting this bootsector will be loaded at address 7C00 hex in memory.

    BITS 16  ; working in x86 real mode -- 16 bit. Also ommitted "org 7C00h" since there is no absolute addressing anywhere.    

    mov dx, 07C0h  ; Making sure that the register "ds" which holds the base address of the data segment
    mov ds, dx     ; is 07C0 hex which when left shifted by 4 bits will be 7C00 hex, program starting address.
    mov si, string  ; The address of the first character of the string is moved into register si.
    mov ah, 0Eh     ; Setting up teletype mode by "moving 0E hex into ah" before calling BIOS video interrupt 10 hex.
    up:             ; Label "up" for looping to print out each character of the string one by one.
    cmp byte[ds:si], 5   ; Comparing each character of the string with number 5 -- 05 hex.
    je exit            ; If the above comparision is true jump to label "exit", else continue.
    mov al, byte[ds:si]  ; Moving the character to be printed into register al before calling interrupt 10 hex.
    int 10h       ; Calling BIOS video interrupt which prints the character in AL onto the screen.
    inc si      ; Incrementing the register si to point to the next character in the string.
    jmp up      ; Jump to label "up" to repeat the same process for the next character.
    exit:      ; label "exit" to exit the loop.
    jmp $      ; Hey Processor get stuck in a never ending loop. --- by jumping to the same instruction forever.

    string db "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.",5
    times 510 - ($ - $$) db 0   ; Making sure we fill up the remaining of 510 bytes of the boot sector with zeros.
    dw 0xAA55       ; Finally adding the boot signature AA55 hex, 2 bytes to make our sector bootable.

以下是代码的截图:

enter image description here

P.S。抱歉,但谦卑地拒绝建议在BIOS视频中断中使用其他模式来执行任务,因为我应该只使用电传打字模式。

0 个答案:

没有答案