Page 1 of 1

Assembly needs on a operative system

Posted: Sun Apr 15, 2012 1:26 pm
by Claudiop
From what i know, and from what i've read before the need for handcoded assembly is just on the bootloader and on specific parts of the kernel right?

Im trying to develop some basic OS just to learn and to gain experience but to be honest i am now learning assembly and the book i am reading it's horrible to read (at least on the chapter i am reading).

The book that i am reading is "Assembly Step by Step, Programming With Linux" from Jeff Duntemann and i cannot simply understand the 4th chapter (Addressing). It is awfully confuse and i've spent an entire day to read like 10 pages and i am still left with doubts.

Where is the problem, is the book that is really hard to understand or i am the problem?
Is there anyway to simply skip the whole assembly thing, or is there an easier way to learn at least this chapter?

If i use a thirty party boot-loader (like grub) may i do the rest like there is no such thing(assembly) in the world?
Regards

Re: Assembly needs on a operative system

Posted: Sun Apr 15, 2012 1:34 pm
by xenos
Even in you use something like GRUB, you'll need some assembly for things like loading the GDT / IDT registers, accessing control registers or model specific registers and things like that. And even if your kernel is mainly written in a high level language, you need at least to understand assembly code as soon as you start debugging your kernel. So in general it is a good idea to learn assembly already before you start writing your kernel.

There is a list of recommended books in some sticky thread here in the forum which might help you, including links to some online assembly tutorials.

Re: Assembly needs on a operative system

Posted: Sun Apr 15, 2012 1:40 pm
by Claudiop
XenOS wrote:Even in you use something like GRUB, you'll need some assembly for things like loading the GDT / IDT registers, accessing control registers or model specific registers and things like that. And even if your kernel is mainly written in a high level language, you need at least to understand assembly code as soon as you start debugging your kernel. So in general it is a good idea to learn assembly already before you start writing your kernel.

There is a list of recommended books in some sticky thread here in the forum which might help you, including links to some online assembly tutorials.
But should this part (Adressing) be the worst or after it i'll find even worst to spend some hours thinking while the mind blows?

Are you talking about this: http://forum.osdev.org/viewtopic.php?f= ... &start=135 ?

Re: Assembly needs on a operative system

Posted: Sun Apr 15, 2012 2:20 pm
by DavidCooper
Most of the complex addressing stuff can be avoided - your code might not be quite as fast or compact, but what matters most to begin with is just to get it working. You can make your life easiest by simply using SI and DI to line up on addresses in memory, then use instructions like STOSB/W and LODSB/W to move bytes between those addresses and AL/AX. The only other thing you're really going to need is an understanding of how to use MOV to fill a register with an address and how to use MOV to fill a register with a value loaded from an address: the difference between them will be something like: MOV al,name (for the first case), or MOV al,[name] (for the second case), but don't trust my syntax as I don't use assembler. You can also go in the opposite direction: MOV [name],al to send a byte from AL to memory. You could write a whole operating system using assembler without doing anything more complicated in the way of addressing than that.

Re: Assembly needs on a operative system

Posted: Sun Apr 15, 2012 3:19 pm
by Claudiop
Most of the complex addressing stuff can be avoided[...]
This is enough for me ;)
Hey i am still learning the basics i didn't understood anything else of what you said.

Anyway, thanks for the help. I'll try to do my best in learning this "diabolic thing from the beast"...

Re: Assembly needs on a operative system

Posted: Sun Apr 15, 2012 10:01 pm
by Rudster816
Once you get the hang of addressing, everything else will start to fall into place.

Basically, any time you address memory, it will take the form [SOME VALUE], as I'm sure you already know. Without the []'s you'll simply be specifying an immediate.

The value between the []'s can contain any combination of the following three values:

1. A displacement. Basically any immediate value, for example:

Code: Select all

mov WORD [0xB8000], 0x0741
You have the specify the operand size for the assembler to know the correct instruction to generate. Most of the time you don't have the specify it though. E.g.

Code: Select all

mov ax, 0x0741
mov [0xB8000], ax 
Does the same thing. But the assembler knows the size of the AX register, so the operand size (WORD) is implicit.

2. A register. You can treat the value inside any register as "pointer" to a memory location.

Code: Select all

mov eax, 0xB8000
mov WORD [eax], 0x0741
This code does the exact same thing as above, but uses the value inside of EAX as a memory location. It's important to note that you have to use a 32 bit register (unless you're in Real\Long Mode) inside of the []'s. specifying a 16bit\8bit register will typically cause your assembler to spit out an error, although some might automatically assume you meant the 32 bit register (e.g. EAX instead of AX). It's also important to know that the just because you're using a 32 bit register as a memory address, doesn't mean the operand size is 32 bits. As you can see in the example above, the operation size is a WORD.

3. A register with a scale. Almost exactly the same as above, except that you can specify a "scale" which just multiples the value in the register by a certain amount. The scale can be 1, 2, 4, or 8 (only in long mode).

Code: Select all

mov eax, 0x2E000 
mov WORD [eax*4], 0x0741
Again, this is accomplishes the same thing as all of the other examples, since 0x2E000 * 4 = 0xB8000. Although it's not really used properly in this example, I think it's obvious that this addressing mode can be very useful for accessing arrays of WORDs or DWORDs.


Now as I said earlier, you can use any combination of the above three.

Code: Select all

mov [eax + ebx*2 + 0xC0007C00], ecx
Is a perfectly valid instruction. One thing to note that the scale of one is implicit with all assemblers (that I know of), so

Code: Select all

mov [eax + ebx], ecx
Is also a legal instruction. As I'm sure you can guess, in order to get the address to use, the processor simply adds everything up. So...

Code: Select all

mov eax, 0xA0000
mov ebx, 0x2000
mov WORD [eax + ebx*4 + 0x10000], 0x0741
Produces the exact same result as all of the other examples.


Hope that helps to clear things up. I know it took me quite some time to fully grasp how to address memory in assembly.

Re: Assembly needs on a operative system

Posted: Mon Apr 16, 2012 1:52 am
by xenos
Claudiop wrote:But should this part (Adressing) be the worst or after it i'll find even worst to spend some hours thinking while the mind blows?
Well, it certainly depends on what you like and what you dislike ;) The complex addressing possibilities of the x86 architecture are certainly one of the most complicated things when one is learning assembly, but as DavidCooper already pointed out, you don't need it most of the time. For osdev, you'll mostly need stuff like accessing special function registers.
Yes, that's it. The online tutorial I would recommend is the Art of Assembly Programming.

Re: Assembly needs on a operative system

Posted: Wed Apr 18, 2012 10:38 pm
by TreahBlade
Assembly Step by Step, Programming With Linux
I have this book as well on my kindle. Honestly it can be a bit confusing on what the hell hes trying to say. You also have to remember that when your dealing with 16bit assembly and writing OS code its different then when your writing it inside an OS like Linux.

I found the WIKI here at OSDev to be the best reference for figuring out how memory segmentation works and how to address things correctly.

And just so you know I am by no far an expert, and I only understand assembly programming enough to muddle though a basic kernel/bootloader.

P.S. If your going to be messing around with 16bit real mode programming most of the assembly **** around is useless as its for 32bit protected mode.