Reputation: 416
I'm currently working on a tutorial that demonstrates how to build an OS from scratch.
In some section of the tutorial there was some assembly code that demonstrates addressing.
The code simply tries to print 'X' in 4 different ways.
The tutorial claims that only the last 2 ways succeed in printing 'X'.
when i tried that on my machine only the third attempt succeeded
Here is the code :
mov ah,0x0e
;first attempt
mov al,the_secret
int 0x10
;second attempt
mov al,[the_secret]
int 0x10
;third attempt
mov bx,the_secret
add bx,0x7c00 ; 0x7c00 is where bios loads our boot sector code
mov al,[bx]
int 0x10
;fourth attempt
mov al,[0x7c1e]
int 0x10
jmp $
the_secret:
db "X"
times 510 -( $ - $$ ) db 0
dw 0xaa55
Now , i understand why the first two attempts failed.
and i believe that the last two attempts should print X
so why does the fourth attempt fails to print 'X' ?
any help would be greatly appreciated
Thanks
Upvotes: 2
Views: 366
Reputation: 62106
You need to understand segments to understand why one or another may or may not print X.
I'm not going to explain everything on a case by case basis. Instead I'll leave you with a few facts, a few disassemblies and some discussion.
First of all, the BIOS can start your bootsector either with CS=7C0h
and IP=0
or with CS=0
and IP=7C00h
. Both point to the same physical address: 7C0h * 16 + 0
= 0 * 16 + 7C00h
= 7C00h
.
Assuming for the moment that in both cases DS=CS
(whichever it is, 7C0h
or 0
), the CPU will have one of these two different views of the same machine code of your bootsector:
IP instruction bytes instruction
00000000 B40E mov ah,0xe
00000002 B01E mov al,0x1e
00000004 CD10 int 0x10
00000006 A01E00 mov al,[0x1e]
00000009 CD10 int 0x10
0000000B BB1E00 mov bx,0x1e
0000000E 81C3007C add bx,0x7c00
00000012 8A07 mov al,[bx]
00000014 CD10 int 0x10
00000016 A01E7C mov al,[0x7c1e]
00000019 CD10 int 0x10
0000001B E9FDFF jmp word 0x1b
0000001E 58 pop ax ; this is your 'X'
...
or
IP instruction bytes instruction
00007C00 B40E mov ah,0xe
00007C02 B01E mov al,0x1e
00007C04 CD10 int 0x10
00007C06 A01E00 mov al,[0x1e]
00007C09 CD10 int 0x10
00007C0B BB1E00 mov bx,0x1e
00007C0E 81C3007C add bx,0x7c00
00007C12 8A07 mov al,[bx]
00007C14 CD10 int 0x10
00007C16 A01E7C mov al,[0x7c1e]
00007C19 CD10 int 0x10
00007C1B E9FDFF jmp word 0x7c1b
00007C1E 58 pop ax ; this is your 'X'
...
You can clearly see now why some methods of accessing 'X' should work in one case and shouldn't in the other and vice versa.
Now, since the BIOS does not guarantee any particular value in DS
when your bootsector starts executing, you may have DS≠CS
and there are four possible cases here:
CS=0
, DS=7C0h
- some of the methods of accessing X
will workCS=7C0h
, DS=0
- some other of the methods of accessing X
will workCS=0
, DS≠7C0h
- none of the methods of accessing X
will workCS=7C0h
, DS≠0
- none of the methods of accessing X
will workUpvotes: 3