1

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:

enter image description here

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.

Knight
  • 193
  • 1
  • 1
  • 6
  • 1
    A hunch - Do these characters not show up when booting on real hardware using USB? If I had to guess you are booting with real hardware (likely USB). Some BIOSes will overwrite areas it things are the BIOS parameter block at the beginning of a Master Boot Record. I'm guessing that is what may have happened here. – Michael Petch May 18 '17 at 04:32
  • Exactly I'm using a bootable pen drive. – Knight May 18 '17 at 04:35
  • Okay, I think you're going to need a BIOS parameters block. I have an example of one in NASM in this [Stackoverflow answer](http://stackoverflow.com/a/43787939/3857942). Under the section _Real Hardware / USB / Laptop Issues_ there is a BIOS parameter block. Copy everything from label `boot:` to label `main:` into the top of your code and see what happens. – Michael Petch May 18 '17 at 04:38
  • 1
    just wondering - have you ever tried copy-paste? – Iłya Bursov May 18 '17 at 04:56
  • Moving the data a liitle bit to the right on the sector either by appending nop instructions or as you said using a MBR got the code woking, but my concern is if the data is getting overwritten why isn't the code. How does the BIOS decide where to overwrite . Any resources on this overwriting if possible.Thanks. – Knight May 18 '17 at 05:01
  • Some BIOSes do it differently. Dumb BIOSes will *always* assume there is a BIOS parameter block on the USB device and will overwrite parts of the BPB with drive geometry information. It happens to be your string of characters overlaps the area where the BIOS updated information. In other cases BIOSes are smarter and they'll try to look at the first few bytes for a short JMP instruction. If it finds a JMP it assumes there is a BPB present. In your case it appears the BIOS is probably a dumb/simple one and is always assuming the BPB exists. – Michael Petch May 18 '17 at 05:06
  • @Michael Thanks a lot for helping me. – Knight May 18 '17 at 05:35
  • @Lashane Sorry I'm new here didn't know that I could pan over the code. – Knight May 18 '17 at 05:36
  • Weird. I've never had such a "dumb" BIOS that assumed there was a BPB. I've tried on lots of different machines, old and new. Of course, that's with a floppy disk, not a USB drive. Perhaps that is the difference. One other minor point to make this comment worthwhile: you don't need to explicitly specify the DS segment in instructions like `cmp byte[ds:si], 5`, since it is the default. What is the harm in doing so, you say? Well, I used to think the same thing, but apparently the explicit specification causes NASM to emit a different (longer) opcode with segment override. – Cody Gray - on strike May 19 '17 at 08:05
  • @CodyGray : A standard floppy disk won't have this issue. This is specifically for booting from USB where the BIOS is set for Floppy Drive emulation. With USB floppy emulation, overwriting the BPB with the drive geometry information of the device is almost the norm. Some BIOSes try to detect the presence of the BPB before writing, some don't. This type of question comes up frequently on SO these days, although the effects may be different. Some people don't have data that gets overwritten but the code does and the bootlaoder code they write seems to not work entirely as expected. – Michael Petch May 20 '17 at 14:03

0 Answers0