kzinti wrote:TheGameMaker90 wrote:
org 0, sets CS to zero, correct?
No, org 0 is an assembler directive and it doesn't generate any code. What it does is tell the assembler that CS will be 0 when executing the instructions you write after it.
"org" is short for "origin" and is used to tells the assembler at which address your intend to load/execute your code.
0x7C00 can be represented in many ways using 16 bits seg:offset addresses: 0x00:0x7C00, 0x7C0:0x0000, etc.
Here is what I would recommend you do (this is the easiest one to understand and likely what you want):
Code: Select all
org 0 # Tell your assembler that CS = 0, but no instructions issued
ljmp $0, _start # Set CS to 0 and IP to the address of _start (really the offset relative to the origin of 0, but that's the same thing as the address)
_start:
# Here you want to set DS = SS = 0
Or alternatively (but I don't recommend it):
Code: Select all
org 0x7C00 # Tell your assembler that CS = 0x7C0, but no instructions issued
ljmp $0x7C0, _start # Set CS to 0x7C0 and IP to the address of _start minus 0x7C00 (i.e. the offset of _start from the origin you set to 0x7C00)
_start:
# Here you want to set DS = SS = 0x7C0
TheGameMaker90 wrote:
Like I said before. Then ds=0x7C00. What of es in this case though?
Clearly you don't understand seg:offset addressing in 16 bits mode. I suggest you read on it before continuing to try to hack something together. The short version is that the effective address of a seg::offset address is "segment * 16 + offset". If you set ds to 0x7C00, you will end up accessing memory in the 0x7C000+ range which is clearly not going to work. If you don't see es, then you don't know what the effective addresses will be when you access something using the es segment.
Pay attention to what people write here: 0x7C0 and 0x7C00 are not typos. They are different numbers. When you multiply 0x7C0 by 16, you get 0x7C00.
Here we go again. I just freaking said that. I switched over to NASM assembly for a moment and I know that about CS. NASM assembly is slightly different than GAS assembly and I know wehat org stands for. I spent a little time learning NASM assembly before I even got started with OS dev, granted not much, but I know the basics.
Although I wasn't sure you could use org like that in GAS assembly. I read somewhere that they are different, despite being named similarly. I will however try your suggestion because my way doesn't seem to yield any results. But doesn't _start require a '$' as well? Maybe not. I'll try it momentarily.
And I never said they were. If you read one of my previous posts you'd see that I just finished saying that DS=AX * 16 so if ax = 0x07C0, then DS = 0x7C00. I know that. I also realized that regardless of how it's written if CS=0, then DS and ES would both be 0 because anything X 0 = 0. Not stupid here.
Edit:
Okay, I tried your idea and got this:
boot.S:8: Error: no such instruction: `org 0'
boot.S:9: Error: operand type mismatch for `ljmp'
Like I said. org is different in GAS and I'm pretty sure I need a '$' in front of _start. Also it still fails to boot when I do that and remove org. I changed it to .org 0 and ljmp $0, $_start and it says:
Booting from hard disk...
Boot failed: Could not read the boot disk
Booting from DVD/CD...
Boot Failed: Could not read from CDROM (code 0003)
Booting from ROM...
iPXE (PCI 00:03.0) starting execution...ok
...
Also I've tried to find resources on how es relates to ax and all of those (<- lazy explanation here), but to no avail.
This is using QEMU.
You should know the rest. It doesn't boot when I have any kind of jump in GAS.
Again, I'll post my github repo:
https://github.com/gamemaker90/Custom-Bootloader.git
Okay, here's a pointer. Is it the linker in my Makefile?
I just noticed something! When I do hexdump boot.bin, I noticed that the magic number is in the wrong spot. It's supposed to be @0x1FE which is hex for 510. How do I fix this?
I think it's because of the offset from the ljmp personally. I could be wrong.