2

I am learning about boot sectors. I downloaded nasm-installer-x64.exe from the NASM website. My operating system is win7-64bit. When I run the following code it does not work correctly

mov ah, 0x0e;

mov al, the_secret;
int 0x10;

mov al, [the_secret];
int 0x10;

mov bx, [the_secret];
add bx, 0x7c00;
mov al, [bx];
int 0x10;

mov al, [0x7c1e];
int 0x10;

jmp $;

the_secret:;
    db 'X';

times 510-($-$$) db 0;
dw 0xaa55;
Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
  • 2
    What makes you think `times 510-($-$$) db 0` does not work? Seems fine to me. Maybe you have some other issue with your bootloader? – Michael Petch Mar 17 '16 at 06:22
  • Thank you very much. The image file generated from my asm codes is not correct. Firstly, it contains 526 bytes which is supposed to be 512 bytes. Secondly, it ends up with 0x5500 which should be 0x55aa. I don't know why this happens... – Xiaosong He Mar 17 '16 at 13:25
  • I found that, the phenomena I described above is caused by the difference between the result compiled by nasm and the result writed into my image file. I use a command `nasm -f bin boot_sect.asm -o boot_sect.bin`, is that correct? – Xiaosong He Mar 18 '16 at 13:18
  • That is correct. If you look at the bottom of my answer I gave an example of how to assemble it, and that matches what I suggested. What commands do you use to put the bootsector on the disk? – Michael Petch Mar 18 '16 at 14:33
  • if you don't have the _DD_ command available, I recommend it as a useful tool you can get for Windows that can be used to build disk images. It can be downloaded from here: http://www.chrysocome.net/downloads/dd-0.6beta3.zip – Michael Petch Mar 18 '16 at 14:36
  • Are you somehow using the windows `copy` command to add files together to produce your disk image? – Michael Petch Mar 18 '16 at 14:58
  • Forgive me, I didn't produce an image file. What I said above, "the image file", is actually the file `boot_sect.bin`. A CPU emulator, here I use `bochs`, will load the BIN file to verify my assembly codes. – Xiaosong He Mar 19 '16 at 11:06
  • I also noticed that, my codes work well after I put your codes from `xor ax,ax` to `cld` to the front of my codes. I think I must read your [General Bootloader Tips](http://stackoverflow.com/questions/32701854/boot-loader-doesnt-jump-to-kernel-code/32705076#32705076) carefully to deepen my understanding on bootloader. I am just interested in this scope recently. Anyway, thanks a lot. – Xiaosong He Mar 19 '16 at 11:13

2 Answers2

4

I don't believe there is anything wrong with times 510-($-$$) db 0. It seems to me your are attempting to find the proper way to access the variable the_secret and then display it to the screen. I'll provide one mechanism based on this attempt which has the most promise:

mov al, [the_secret];
int 0x10;

If you set up DS properly, set an origin point using org 0x7c00 and make sure BH is set to the page number you want to write to (you want 0) then the following code should work:

[bits 16]          ; 16-Bit code
[org 0x7c00]       ; Set the origin point to 0x7c00

start:
    xor ax,ax      ; We want a segment of 0 for DS for this question
    mov ds,ax      ;     Set AX to appropriate segment value for your situation
    mov es,ax      ; In this case we'll default to ES=DS
    mov bx,0x8000  ; Stack segment can be any usable memory

    mov ss,bx      ; This places it with the top of the stack @ 0x80000.
    mov sp,ax      ; Set SP=0 so the bottom of stack will be @ 0x8FFFF

    cld            ; Set the direction flag to be positive direction

    mov ah, 0x0e
    mov al, [the_secret]  ; al = character from memory DS:[the_secret]
    xor bh, bh            ; bh = 0 = video page number
    int 0x10;

    jmp $

the_secret:;
    db 'X';

times 510-($-$$) db 0
dw 0xAA55

The start up code sets DS to zero since we set an origin point of 0x7c00. The bootloader is loaded at 0x0000:0x7c00 (physical address 0x07c00). This ensures accessing the variable the_secret will be done properly. mov al, [the_secret] is the equivalent of saying mov al, ds:[the_secret]. If the DS segment register is not set properly, and the origin point isn't set properly, the memory access will not read from the proper location.

INT 0x10/AH=0x0E requires a page number to be set. The first video display page is 0, BH should be set accordingly.

More on the other setup instructions can be found in my StackOverflow answer that contains General Bootloader Tips.

The code I have presented should display X to the console if properly written to a disk image.


To assemble this code and produce a disk image (in my example a 720k floppy):

nasm -f bin bootload.asm -o bootload.bin
dd if=/dev/zero of=disk.img bs=1024 count=720
dd if=bootload.bin of=disk.img bs=512 count=1 conv=notrunc

The first command does the assembling of bootload.asm into a flat binary file called bootload.bin. The second command produces a zero filled disk image (disk.img) of size 1024 * 720 (720kb floppy), and the last command copies 512 bytes of data from bootload.bin to the first sector of the disk image. conv=notrunc tells DD not to truncate the file after writing. If you were to leave that off disk.img would be 512 bytes long after the bootsector was written.

Community
  • 1
  • 1
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • Thank you for you elaborate explanation. It helps me a lot, really. – Xiaosong He Mar 17 '16 at 13:32
  • I recently run "kernel" successfully. After I went through it, I understood more about this code. Today, I find that you mentioned `bh` is needed to be set since it involves the page number. But, I actually did not set it at all. Could you explain more about it for me? What is page number…… – Xiaosong He Mar 23 '16 at 14:49
  • My answer provides a link to information for *Int 10h/ah=0eh*: http://www.ctyme.com/intr/rb-0106.htm . Ralf Brown's interrupts lists has become a standard for BIOS/DOS information. At the link you should notice it says `BH = page number` . You can potentially have more than one page of video memory to display to. Page 0 is the default when a system boots. It is a good idea to set BH to zero for this _INT_ call to make sure you write to the default page. Failure to do this may result in the text not appearing. There are a limited number of pages, and possible _BH_ wasn't valid so defaults to 0 – Michael Petch Mar 23 '16 at 14:58
  • I got it. Thanks a lot~ – Xiaosong He Mar 24 '16 at 01:46
0

You can try just replacing the hex of the code snippet. It should be caused by the new hex corrupting the MBR format