Question

So, I decided to learn Assembly Language for the 80x86 this summer. I picked up four books on assembly. So far I've read the first two and I'm half way though the third one and I think I understand everything that has been presented. I've written a few Hello World programs as well as other little exercises from the book and I feel very comfortable with the language. However, there is one thing that none of the books have addressed so far and it's the thing that I'm most interested in. That is, How do you address the hardware directly from assembly language? So far in the books the author has used system calls, jumps to specific functions in memory, and interrupts, but these methods rely on software already present in the system.

I'm writing my programs using NASM and loading them into an old Pentium I computer. I'm not using any OS right now, just the BIOS. I guess what I'm trying to do is write my little OS that is autonomous and does not rely on the BIOS (except for initial boot). Can anyone help me?

Was it helpful?

Solution

How are you booting and running your code with BIOS only?

Assuming you really are only using BIOS, or even if you were using DOS that would be okay. You simply address the hardware, specify the address of some hardware register right in the instruction or put that address in a register and do a register indirect read or write.

Access to hardware is only difficult when an operating system is in the way, making the hardware do something useful of course is much easier with an operating system, naturally.

Fortunately the BIOS has enumerated the pci(e) hardware, that is the PC way of doing things, so you can use some DOS utilities I think to find out how the hardware has been enumerated. Another "PC way of doing things" the PCI(e) address for the hardware is also the x86 address, the two address spaces overlap, so once you get the PCI(e) address for some peripheral then you can use that address in your code. naturally since the pcie window is relatively small for things like video you still have to page through the peripheral memory, but that is peripheral specific not a PC or x86 thing.

if your motherboard has a serial port/uart that would be the best place to start with directly accessing hardware.

Even better would be to use a simulator pcemu or other, rather than start on hardware, depending on your choice of simulator you may have much better visibility into what is going on and a peripheral like a uart may be even that much simpler as you might not have to initialize it just start throwing bytes at it (until you learn more).

OTHER TIPS

dwelch is completely right, but I want to answer your question on a more basic level:
In most cases, you access hardware via control and status registers. In the most simple case e.g. you want to read from a serial line, and you are waiting for a new character to arrive. A status register could set a bit "ready", and then you read the character from another register.
This means you have to address registers like memory addresses. Again in most cases this is done by mapping registers to you address space, i.e. the registers have memory addresses in an address range where no memory is, e.g. the topmost addresses. Then you can use most instructions that access the memory, e.g. load and store.
In the real world the situation is more complex, because the CPU uses virtual addresses that are mapped to the physical address space (where the registers are located) by a programmable memory management unit.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top