What is NASM doing with this code to break it?

Programming, for all ages and all languages.
Post Reply
duran
Posts: 22
Joined: Mon Jun 02, 2008 5:22 pm
Location: Sydney, Australia

What is NASM doing with this code to break it?

Post by duran »

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.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: What is NASM doing with this code to break it?

Post by Candy »

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.
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: What is NASM doing with this code to break it?

Post by qw »

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.
If NASM does not assign the right absolute address to a symbol, than long jumping won't help.

Anyway, I compiled with NASM 2.08 with no problems.

Duran, what were the incorrect addresses that you got first?
User avatar
Love4Boobies
Member
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?

Post by Love4Boobies »

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 ]
User avatar
Firestryke31
Member
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?

Post by Firestryke31 »

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
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?
User avatar
Owen
Member
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?

Post by Owen »

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.
Short jumps will work irrespective of where your code is compiled. Remember: x86 doesn't have an absolute near jump instruction.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: What is NASM doing with this code to break it?

Post by Candy »

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).
Wow... That doesn't happen often, that finding an error in your code execution ends up in finding a bug in the compiler/assembler.

Do wonder what mistake this is when the same code base messes up on Windows and runs fine on Ubuntu.
User avatar
Love4Boobies
Member
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?

Post by Love4Boobies »

Owen wrote:
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.
Short jumps will work irrespective of where your code is compiled. Remember: x86 doesn't have an absolute near jump instruction.
Maybe an example will help...

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 ]
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: What is NASM doing with this code to break it?

Post by Gigasoft »

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.
User avatar
Love4Boobies
Member
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?

Post by Love4Boobies »

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 ]
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: What is NASM doing with this code to break it?

Post by Gigasoft »

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.)
Attachments
flpfatld.asm
(5.28 KiB) Downloaded 87 times
Post Reply