lesson 3, boot sector with memory addressing

pull/6/head
Carlos Fenollosa 10 years ago
parent 3a8b9086d4
commit 8211b950b1

@ -1,13 +1,13 @@
*Concepts you may want to Google beforehand: memory offsets, pointers*
The only goal of this lesson is to learn where the boot sector is stored
Please open page 14 [of this document](
http://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf)<sup>1</sup>
and look at the figure with the memory layout.
I could just go ahead and tell you that it starts at `0x7C00`, but it's
better with an example.
The only goal of this lesson is to learn where the boot sector is stored
I could just go ahead and tell you that the BIOS places it at `0x7C00`, but an
example with wrong solutions will make things clearer.
We want to print an X on screen. We will try 4 different strategies
and see which ones work and why.
@ -23,7 +23,7 @@ Then we will try to access `the_secret` in many different ways:
1. `mov al, the_secret`
2. `mov al, [the_secret]`
3. `mov al, the_secret + 0x7C00`
4. `mov al, 2d + 0x7C00`, where `2d` is the actual position of the X in the binary
4. `mov al, 2d + 0x7C00`, where `2d` is the actual position of the 'X' byte in the binary
Take a look at the code and read the comments.
@ -33,6 +33,21 @@ the bytes following 1 and 2 are just random garbage.
If you add or remove instructions, remember to compute the new offset of the X
by counting the bytes, and replace `0x2d` with the new one.
Please don't continue onto the next file unless you have 100% understood
the boot sector offset and memory addressing.
Now, since offsetting `0x7c00` everywhere is very inconvenient, assemblers let
us define a "global offset" for every memory location, with the `org` command:
```nasm
[org 0x7c00]
```
Go ahead and open `boot_sect_memory_org.asm` and you will see the canonical
way to print data with the boot sector, which is now attempt 2. Compile the code
and run it, and you will see how the `org` command affects each previous solution.
Read the comments for a full explanation of the changes with and without `org`
-----

@ -10,7 +10,7 @@ int 0x10
; attempt 2
; It tries to print the memory address of 'the_secret' which is the correct approach.
; However, BIOS starts loading at address 0x7c00
; However, BIOS places our bootsector binary at address 0x7c00
; so we need to add that padding beforehand. We'll do that in attempt 3
mov al, "2"
int 0x10
@ -19,7 +19,9 @@ int 0x10
; attempt 3
; Add the BIOS starting offset 0x7c00 to the memory address of the X
; and then dereference the contents of that pointer
; and then dereference the contents of that pointer.
; We need the help of a different register 'bx' because 'mov al, [ax]' is illegal.
; A register can't be used as source and destination for the same command.
mov al, "3"
int 0x10
mov bx, the_secret
@ -29,19 +31,21 @@ int 0x10
; attempt 4
; We try a shortcut since we know that the X is stored at byte 0x2d in our binary
; That's smart but ineffective, we don't want to be recounting label offsets
; every time we change the code
mov al, "4"
int 0x10
mov al, [0x7c2d]
int 0x10
jmp $
jmp $ ; infinite loop
the_secret:
; ASCII code 0x58 is stored just before the zero-padding
; on this code that is at byte 0x2d (check it out using xdd)
; ASCII code 0x58 ('X') is stored just before the zero-padding.
; On this code that is at byte 0x2d (check it out using 'xdd file.bin')
db "X"
; zero padding and magic bios number
times 510-($-$$) db 0
dw 0xaa55

@ -0,0 +1,47 @@
[org 0x7c00]
mov ah, 0x0e
; attempt 1
; Will fail again regardless of 'org' because we are still addressing the pointer
; and not the data it points to
mov al, "1"
int 0x10
mov al, the_secret
int 0x10
; attempt 2
; Having solved the memory offset problem with 'org', this is now the correct answer
mov al, "2"
int 0x10
mov al, [the_secret]
int 0x10
; attempt 3
; As you expected, we are adding 0x7c00 twice, so this is not going to work
mov al, "3"
int 0x10
mov bx, the_secret
add bx, 0x7c00
mov al, [bx]
int 0x10
; attempt 4
; This still works because there are no memory references to pointers, so
; the 'org' mode never applies. Directly addressing memory by counting bytes
; is always going to work, but it's inconvenient
mov al, "4"
int 0x10
mov al, [0x7c2d]
int 0x10
jmp $ ; infinite loop
the_secret:
; ASCII code 0x58 ('X') is stored just before the zero-padding.
; On this code that is at byte 0x2d (check it out using 'xdd file.bin')
db "X"
; zero padding and magic bios number
times 510-($-$$) db 0
dw 0xaa55
Loading…
Cancel
Save