hshihab
hshihab

Reputation: 416

Addressing in Assembly

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

Answers (2)

Alexey Frunze
Alexey Frunze

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 work
  • CS=7C0h, DS=0 - some other of the methods of accessing X will work
  • CS=0, DS≠7C0h - none of the methods of accessing X will work
  • CS=7C0h, DS≠0 - none of the methods of accessing X will work

Upvotes: 3

bob el 3azama
bob el 3azama

Reputation: 1

Use tasm instead of nasm Theoretcically it will work

Upvotes: -2

Related Questions