What is NASM doing with this code to break it?
What is NASM doing with this code to break it?
Hello all,
I was playing about with the real mode keyboard interrupt code from the wiki (http://wiki.osdev.org/Keyboard#Simple_k ... _real_mode) this morning, but I couldnt get it working as is.
I assembled it as so:
nasm -f bin -o boot.img boot.asm
and then loaded it into bochs. pressed keys, nothing.
using the GUI debugger for bochs I noticed that the code entry points that nasm had resolved keyboard_handler and hex_chars to were incorrect. i modified the code to use absolute memory addresses (0x7C18 and 0x7C30, with a nop inserted after jmp $ for alignment purposes). After this, all worked hunky dory.
What i don't understand is, why did Nasm assemble this using such seemingly arbitrary addresses?
i've noticed this same behaviour using other code written by myself, but i assumed it was something silly that i must have been doing. this isn't my code though and seems to be doing the same thing.
EDIT: It appears as though this is a bug in the Nasm 2.09rc1 binary hosted on the nasm home page. the code assembles correctly using the Ubuntu Hardy nasm.
I was playing about with the real mode keyboard interrupt code from the wiki (http://wiki.osdev.org/Keyboard#Simple_k ... _real_mode) this morning, but I couldnt get it working as is.
I assembled it as so:
nasm -f bin -o boot.img boot.asm
and then loaded it into bochs. pressed keys, nothing.
using the GUI debugger for bochs I noticed that the code entry points that nasm had resolved keyboard_handler and hex_chars to were incorrect. i modified the code to use absolute memory addresses (0x7C18 and 0x7C30, with a nop inserted after jmp $ for alignment purposes). After this, all worked hunky dory.
What i don't understand is, why did Nasm assemble this using such seemingly arbitrary addresses?
i've noticed this same behaviour using other code written by myself, but i assumed it was something silly that i must have been doing. this isn't my code though and seems to be doing the same thing.
EDIT: It appears as though this is a bug in the Nasm 2.09rc1 binary hosted on the nasm home page. the code assembles correctly using the Ubuntu Hardy nasm.
Re: What is NASM doing with this code to break it?
Your BIOS may use 0x7C0:0x0000 as target instead of 0x0000:0x7C00. That causes your ORG to be messed up & all the jumps to go haywire.
Normalize the segment by a long jump at the start of your code first.
Normalize the segment by a long jump at the start of your code first.
Re: What is NASM doing with this code to break it?
If NASM does not assign the right absolute address to a symbol, than long jumping won't help.Candy wrote:Your BIOS may use 0x7C0:0x0000 as target instead of 0x0000:0x7C00. That causes your ORG to be messed up & all the jumps to go haywire.
Normalize the segment by a long jump at the start of your code first.
Anyway, I compiled with NASM 2.08 with no problems.
Duran, what were the incorrect addresses that you got first?
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: What is NASM doing with this code to break it?
Yes it will since 07C0:0000 and 0000:7C00 resolve to the same physical address. The problem isn't with relative jumps but short jumps - a long jump will make sure that all short jumps work for your given origin.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
- Firestryke31
- Member
- Posts: 550
- Joined: Sat Nov 29, 2008 1:07 pm
- Location: Throw a dart at central Texas
- Contact:
Re: What is NASM doing with this code to break it?
According to the comments in the bug report on the NASM site, this was in fact a bug with NASM. Jumping to a equivalent segment would not have fixed it as NASM was flat out wrong (0x9300s instead of 0x7c00s).
http://sourceforge.net/tracker/?func=de ... tid=106208
http://sourceforge.net/tracker/?func=de ... tid=106208
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: What is NASM doing with this code to break it?
Short jumps will work irrespective of where your code is compiled. Remember: x86 doesn't have an absolute near jump instruction.Love4Boobies wrote:Yes it will since 07C0:0000 and 0000:7C00 resolve to the same physical address. The problem isn't with relative jumps but short jumps - a long jump will make sure that all short jumps work for your given origin.
Re: What is NASM doing with this code to break it?
Wow... That doesn't happen often, that finding an error in your code execution ends up in finding a bug in the compiler/assembler.Firestryke31 wrote:According to the comments in the bug report on the NASM site, this was in fact a bug with NASM. Jumping to a equivalent segment would not have fixed it as NASM was flat out wrong (0x9300s instead of 0x7c00s).
Do wonder what mistake this is when the same code base messes up on Windows and runs fine on Ubuntu.
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: What is NASM doing with this code to break it?
Maybe an example will help...Owen wrote:Short jumps will work irrespective of where your code is compiled. Remember: x86 doesn't have an absolute near jump instruction.Love4Boobies wrote:Yes it will since 07C0:0000 and 0000:7C00 resolve to the same physical address. The problem isn't with relative jumps but short jumps - a long jump will make sure that all short jumps work for your given origin.
1) BIOS origin is 07C0:0000 but the boot sector expects 0000:7C00.
2) Next, the boot code attempts a near absolute jump (e.g., jump to offset 7C50h) - those who have read Owen's post, see PS.
3) The jump will be made to 07C0:7C50, which doesn't resolve to the same physical address as 0000:7C50.
However, doing a far jump at the beginning of the boot code will ensure that CS has the value you expect.
PS: I didn't mean "short jumps" in the previous post, my bad. Near absolute is indeed possible on the x86, but not with immediate values.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
Re: What is NASM doing with this code to break it?
Hm, it turns out that my FAT12 boot sector does use absolute code addresses. But, I have only 4 bytes to spare, not enough for a far jump. Perhaps my boot sector is trying to do too much? It provides services to the OS for loading files during the boot process (before drivers have been loaded and hardware has been taken over), and it also handles long filenames and subdirectories.
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: What is NASM doing with this code to break it?
Attach your boot sector here. I am almost entirely sure we can make your code a lot more compact.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
Re: What is NASM doing with this code to break it?
Oh, wait, I was mistaken. I had more bytes to spare than I thought, so it worked out fine.
I'll post it anyway, so perhaps someone can help improve it even further? It is currently untested, so I apologize for any mistakes that may be present.
(This file is in MASM syntax, and is assembled into OMF format, which my custom made linker expects.)
I'll post it anyway, so perhaps someone can help improve it even further? It is currently untested, so I apologize for any mistakes that may be present.
(This file is in MASM syntax, and is assembled into OMF format, which my custom made linker expects.)
- Attachments
-
- flpfatld.asm
- (5.28 KiB) Downloaded 87 times