16 bit addressing problem

Programming, for all ages and all languages.
Post Reply
User avatar
eino
Member
Member
Posts: 49
Joined: Fri Sep 16, 2011 10:00 am
Location: Finland

16 bit addressing problem

Post by eino »

Hi, I'm playing with some bios calls and 16 bit assembly stuff. I boot my code with MikeOS's bootloader. Stack works since I can do C style calls.

Anyways, my problem is that I cannot seem to be able to load the byte at font2 to a register. When ever I directly mov the same byte to a register it works.

What am I doing wrong?

Here's the code... (fraction of a thing that should later on be able to draw 8x8 and 8x16 fonts...)

Code: Select all

jmp skip
	font2:	db 10101010b
skip:
	mov al, 0x10
	mov ah, 0x00
	int 0x10

	push word 50
	push word 50
	push word 550
	push word 250
	call draw_rect
	add sp, 8

	mov ah, 0
	mov al, 10101010b ; IF I CHANGE THIS TO mov al, [font2] or mov al, font2 it stops working!

	mov bh, 0
	mov bl, 10000000b ; THIS IS A MASK I SHR ON EVERY ITERATION TO SEE IF PIXEL IS ON OR OFF IN WHAT SHOULD BE AT font2

	mov si, 0
	forloop:
		
		cmp si, 8
		je forend

		mov cl, al
		and cl, bl

		cmp cl, 0
		je skip2

			push word 0x06		;color
			push word si		;x coordinate
			push word 1d		;y coordinate for now.
			call draw_pixel
			add sp, 6

		skip2:
		
		shr bl, 1
		inc si

		jmp forloop

	forend:
I'm Eino Tuominen from Finland, a web software dev learning low level stuff and reading / trying out kernel dev
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: 16 bit addressing problem

Post by qw »

Does DS have the correct value? Since font2 is inside executable code, DS should equal CS.
User avatar
eino
Member
Member
Posts: 49
Joined: Fri Sep 16, 2011 10:00 am
Location: Finland

Re: 16 bit addressing problem

Post by eino »

Yes. I copied the setup from MikeOs

Code: Select all

mov ax, 07C0h		; Set up 4K stack space after this bootloader
	add ax, 288		; (4096 + 512) / 16 bytes per paragraph
	mov ss, ax
	mov sp, 4096

	mov ax, 07C0h		; Set data segment to where we're loaded
	mov ds, ax
I'm Eino Tuominen from Finland, a web software dev learning low level stuff and reading / trying out kernel dev
User avatar
Minoto
Member
Member
Posts: 89
Joined: Thu May 12, 2011 7:24 pm

Re: 16 bit addressing problem

Post by Minoto »

eino wrote:

Code: Select all

mov ax, 07C0h		; Set up 4K stack space after this bootloader
	add ax, 288		; (4096 + 512) / 16 bytes per paragraph
	mov ss, ax
	mov sp, 4096

	mov ax, 07C0h		; Set data segment to where we're loaded
	mov ds, ax
That doesn't set ds equal to cs -- it sets ds to 0x7c0, which you assume is in cs. What if the BIOS loaded your code to 0:0x7C00 instead?
Those who understand Unix are doomed to copy it, poorly.
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: 16 bit addressing problem

Post by Gigasoft »

That doesn't set ds equal to cs -- it sets ds to 0x7c0, which you assume is in cs.
No, he doesn't.
What if the BIOS loaded your code to 0:0x7C00 instead?
That's the exact same address.

The value of CS of course does not matter. What's important is what's in the .org directive. In this case, it should be 0.
User avatar
Minoto
Member
Member
Posts: 89
Joined: Thu May 12, 2011 7:24 pm

Re: 16 bit addressing problem

Post by Minoto »

Gigasoft wrote:
That doesn't set ds equal to cs -- it sets ds to 0x7c0, which you assume is in cs.
No, he doesn't.
Yes, he does. We're looking at a fragment of code that could be running well after the bootloader here; who knows what a far jump might have loaded into cs at this point? If he's accessing data that's located inside this code by its offset into the code, then ds needs to match cs. Let's say the offset of font2 is 100h -- trying to load it from 7c0h:100h isn't going to work very well if the code that it's embedded in is loaded higher up at 900h:0h, for example.
Those who understand Unix are doomed to copy it, poorly.
freecrac
Member
Member
Posts: 69
Joined: Thu Sep 20, 2012 5:11 am
Location: germany hamburg

Re: 16 bit addressing problem

Post by freecrac »

Hello.

What is happend with using a segment override prefix?

Code: Select all

mov al, cs:[font2]
If the move instruction with a segment override prefix with CS get the byte from "font2", than the segment address in DS is not the same.

Dirk
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: 16 bit addressing problem

Post by Gigasoft »

Minoto wrote:We're looking at a fragment of code that could be running well after the bootloader here; who knows what a far jump might have loaded into cs at this point? If he's accessing data that's located inside this code by its offset into the code, then ds needs to match cs.
Ah, but now you're changing your argument. You're still wrong, though. The value of CS is totally irrelevant.
Minoto wrote:Let's say the offset of font2 is 100h -- trying to load it from 7c0h:100h isn't going to work very well if the code that it's embedded in is loaded higher up at 900h:0h, for example.
Obviously, 7d00h does not equal 9100h, a basic mathematical fact that again does not depend on the current value of CS. In that case, the program should start with .org 1400h.
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: 16 bit addressing problem

Post by Bender »

Try this:

Code: Select all

[section .text]
test_for_any_BS_happening:
;; Set al to our variable
mov al, [bs]
;; convert to integer
add al, 48
;; ES to video ram
mov bx, 0xB800
mov es, bx
;; At offset 0
xor di, di
;; green color
mov ah, 0x02
;; write to video memory
mov [es:di], ax
;; just halt to ensure that the "other code" doesn't modify the Video RAM. :)
cli
hlt
_halt_forever:
jmp _halt_forever
[section .data]
bs: db 6
If everything works you shall see a '6' on the top left corner of screen, if it does there is something wrong elsewhere, if not
well further investigation will be required. :P
IF I CHANGE THIS TO mov al, [font2] or mov al, font2 it stops working!
As a side note there is a large difference between the two, if used correctly mov al, [font2] is the one you should
be using, as using a square bracket will give AL the value of font2, however if you use it without the brackets it'll
give you the address of font2, remember that AL is a 8-bit register, and addresses are 16-bit, that'll end up with a
wrong address thus use AX/BX/CX/DX/SI/DI for getting addresses. :)
EDIT: corrected the code to use BX instead of AX.
mov ax, 07C0h ; Set data segment to where we're loaded
mov ds, ax
I prefer this:

Code: Select all

push cs
pop ds
;; if you want a non-stack approach this one is also okay...
mov ax, cs
mov ds, ax
The first one takes 5-bytes and the second one takes 2-bytes and the last one takes 4 bytes, the last 2 are safer if you want DS=CS.
That doesn't set ds equal to cs -- it sets ds to 0x7c0, which you assume is in cs. What if the BIOS loaded your code to 0:0x7C00 instead?
Well,
0x7C0*0x10 + 0x0000 = 0x7C00
0x0000*0x10 + 0x7C00 = 0x7C00
Doesn't matter how you address it.
Like writing or reading a byte from 0x0000:0x7C00 is same as reading or writing it to or from 0x7C0:0x0000 after all as Gigasoft said they'll translate to the same address.....
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: 16 bit addressing problem

Post by Octocontrabass »

Bender wrote:
That doesn't set ds equal to cs -- it sets ds to 0x7c0, which you assume is in cs. What if the BIOS loaded your code to 0:0x7C00 instead?
Well,
0x7C0*0x10 + 0x0000 = 0x7C00
0x0000*0x10 + 0x7C00 = 0x7C00
Doesn't matter how you address it.
Like writing or reading a byte from 0x0000:0x7C00 is same as reading or writing it to or from 0x7C0:0x0000 after all as Gigasoft said they'll translate to the same address.....
They do translate to the same address.

Now try doing "mov ax, subroutine" followed by "call ax". Will that translate to the same address regardless of the value of CS?
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: 16 bit addressing problem

Post by Bender »

Now try doing "mov ax, subroutine" followed by "call ax". Will that translate to the same address regardless of the value of CS?
That should give AX the offset of the subroutine label, if the subroutine label is in another segment then that would mess up, so the value of CS is important in this case.
I guess I am seeing your point.
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: 16 bit addressing problem

Post by Octocontrabass »

Jumping between segments obviously requires reloading CS; I'm talking about attempting to do an absolute jump without changing the value in CS, such as when all of the code is within one segment.

Let's say the assembler ends up putting the first opcode of the subroutine at offset 0x0123 in the boot sector. Won't there be a problem if some computers jump to 0x0000:0x0123, and other computers jump to 0x07C0:0123?
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: 16 bit addressing problem

Post by Gigasoft »

Changing the subject does not equate to making a point. All you've done is invent an entirely different imaginary problem that has nothing to do with what is being discussed.
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: 16 bit addressing problem

Post by Octocontrabass »

I am trying to point out that the value of CS is important, and that you should avoid using the value set by the BIOS. If that amounts to a change of subject, then I apologize.

In any case, the value of segment registers is important: the assembler is only capable of using a single value for each offset, and it is up to the programmer to set the segment registers so that those offsets point to the correct locations in memory.
Post Reply