A couple bootloader questions

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
caligae
Posts: 3
Joined: Sun Oct 07, 2012 4:55 am

A couple bootloader questions

Post by caligae »

I'm trying to make a simple bootloader that accesses a few bios interrupts, but I'm having a few problems. Here is my code:

Code: Select all

.globl _start
.code16
.org	0x7c00

.text

_start:
/*
*	cli
*
*ljmp	$0, $real_start

*real_start:
*	
*	xorw	%ax, %ax
*	movw	%ax, %ds
*	movw	%ax, %ss
*	movw	$0x2000, %sp
*	sti
*/
	mov	$0x0e41, %ax
	int	$0x10

	mov	$welcome, %si
	call	print_str

	mov	$0x0e5a, %ax
	int	$0x10
	
1:	
	jmp	1b

/* PRINT STRING */

1:
	mov	$0x0007, %bx
	mov	$0x0e, %ah
	int	$0x10

	inc	%si
print_str:
	mov	(%si), %al
	cmp	$0, %al
	jne	1b
	ret

welcome:	.asciz	"Welome, please enter a number\n"


. = _start + 510
	.word	0xaa55
For some reason moving the address of the "welcome" label to %si results in an incorrect address of 0xf821 instead of 0x7c21. I tried changing it in the binary with the dd command, and then it worked correctly. However this doesn't really make sense because the call instruction wasn't affected by the .org directive at all with an address of 0x1a (the correct unrelocated address) according to objdump , yet it still managed to find the "print_str" function. And where does the corresponding instruction "e8 0f 00" specify the address 0x1a?

Also, if I uncomment the commented stuff at the start of the file nothing is displayed at all, not even the "A" character at the start. Have I done something wrong there?

Cheers
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: A couple bootloader questions

Post by Combuster »

I get the idea you're trying to run object code without linking it first, which means that none of your offsets are getting fixed and you just go with whatever the assembler put there as temporary values.

GAS is a dumb assembler can only process stuff as if it were the linux kernel. YASM can read the same syntax but can also do all the things GAS considers religious insults, i.e. the things you just skipped and will otherwise be needing a separate tool for.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
caligae
Posts: 3
Joined: Sun Oct 07, 2012 4:55 am

Re: A couple bootloader questions

Post by caligae »

Ok I figured out I made a stupid mistake. When linking I accidently used the command "ld --oformat=binary -Ttext=0x7c00 -o file2 file" instead of setting the text segment to zero. So the "f8" was double "7c". So the ljmp is also working now. I still dont understand how the call instruction works though, when it has not been relocated by the org directive. Even the un-relocated address appears not to be encoded in the call instruction.

One more thing, I see no mention of the ljmp mnemonic in any documentation. Is that gas specific?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: A couple bootloader questions

Post by Brendan »

Hi,
caligae wrote:Ok I figured out I made a stupid mistake. When linking I accidently used the command "ld --oformat=binary -Ttext=0x7c00 -o file2 file" instead of setting the text segment to zero. So the "f8" was double "7c". So the ljmp is also working now. I still dont understand how the call instruction works though, when it has not been relocated by the org directive. Even the un-relocated address appears not to be encoded in the call instruction.
For the call instruction, the value encoded in the instruction is an offset that is relative to IP. For example, the bytes 0xE8,0x34,0x12 would be "call the address of the next instruction plus 0x1234" and not "call 0x1234".

This means that the address of the code doesn't matter, in the same way that the value of "org" would have no effect in the formula "y = (org + z) - (org + x)". This also means that the assembler can figure it out and the linker probably doesn't need to know about call instructions at all (unless you're calling something in a different object file).
caligae wrote:One more thing, I see no mention of the ljmp mnemonic in any documentation. Is that gas specific?
Most documentation assumes Intel syntax mnemonics, but GAS uses AT&T syntax mnemonics. The "ljmp" would be "jmp (far)" in Intel's manual, and either "jmp far" or just "jmp" in most Intel syntax assemblers/disassemblers, tutorials, etc.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
caligae
Posts: 3
Joined: Sun Oct 07, 2012 4:55 am

Re: A couple bootloader questions

Post by caligae »

Thanks Brendan.
Post Reply