This tiny code below is a bootloader written in assembly language and assembled with The Netwide assembler (NASM) to produce a 512 bytes binary output (Machine code).This is then copied into the first sector of a bootable device and then booted.
Since this is a bootloader it runs in x86 real mode which is 16 bit.
If you have gone through the code, you know that all it does is prints out characters one by one ranging from a-z , A-Z , 1-9 , 0 and finally a dot(.) using BIOS video interrupt 10 hex in teletype mode.
So it is expected to print the following abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.
However somehow magically it's missing the characters c,d,e,f and k resulting in
ab fghij lmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.
I really couldn't figure out where I went wrong,also this is working well in emu8086. So what made this code fail on a real machine.
Thank you for taking time to read this.
; 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.
Here is a screenshot of the code:
P.S. Sorry but humbly rejecting suggestions to use other modes in BIOS video interrupt to do the task as I am supposed to use only teletype mode.