Reputation: 241
I am using NASM to assemble my assembler code. The code I assembled looks like this:
[BITS 32]
[ORG 0]
jmp 07c0h:start
testvar db 0, 0, 0, 0, 0, 0, 4, 8, 15, 16, 23, 42
start:
mov byte [testvar], 47
hang:
jmp hang
times 510-($-$$) db 0
dw 0AA55h
I had problems with another piece of code, I noticed that I couldn't modify memory, so I wrote this piece of code to test if that was actually the case. It was! I copied the assembled machine code to the first sector of a floppy, the program ran (I used MS VirtualPC). I checked RAM memory assigned to Virtual PC and searched for numbers 4 8 15 16 23 42, so that I could find where the binary code was copied. The first byte of the data was not touched. Why is it so?
Upvotes: 1
Views: 227
Reputation: 2755
An issue other than bits 32
being wrong for boot loader code is that you do not set ds
to anything, so it will retain whatever the ROM-BIOS put into it last. You want mov ax, 7C0h
\ mov ds, ax
to fix that (when using org 0
).
Upvotes: 1
Reputation: 5008
Setting "BITS 32" in your source file only affects the opcodes the assembler spits out.
To execute 32bit code, you'll need to change the processor mode to, surprise surprise, 32bit protected mode. Typically, when moving a bit beyond your very first toy bootsector, you'll do your kernel loading in multiple steps. First, the 16bit bootsector, with all it's size constraints. This loads a 16bit bootloader, which in turn can set up protected mode. Some designs keep this 16bit part minimal and further uses a 32bit bootloader for loading the kernel, other designs load the kernel directly from the 16bit bootloader.
I suggest you take a look at http://wiki.osdev.org/Main_Page , http://www.asmcommunity.net/ and http://board.flatassembler.net/ :)
Upvotes: 2
Reputation: 654
The simple answer is that the same code assembled as 32 bit is different than that assembled as 16 bit. Boot sector code (and all loaded code) is run in 16 bit real mode until the CPU mode is switched.
The happy answer is a listing shows the difference.
[BITS 16]
0000000C: C6 06 00 00 2F mov BYTE [testvar], 47
The same code as 32 bit
[BITS 32]
0000000C: C6 05 00 00 00 00 2F mov BYTE [testvar], 47
The equivalent code when run as 16 bit
[BITS 16]
0000000C: C6 05 00 mov BYTE [di], 0
0000000F: 00 00 add [bx+si], al
00000011: 00 2F add [bx], ch
Upvotes: 4
Reputation: 5490
My understanding is that PC compatible machines all start in 16 bit mode (for compatibility reasons). So it seems to me that you need to begin with [BITS 16], even if the first instruction is a jump to to 32 bit mode and is immediately followed by [BITS 32]. See NASM: Mixing 16 and 32 Bit Code.
I'm a little fuzzy on the floppy boot process. Are you sure the code is located where it will actually be executed? Is it possible to single-step through that code?
Upvotes: 0