64-Bit Assembler Addressing

Programming, for all ages and all languages.
Post Reply
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

64-Bit Assembler Addressing

Post by thepowersgang »

I'm attempting to create a 64-Bit version of my OS, and due to a problem in my toolchain (I need to find a 64-bit version of gas) I decided to make it in assembler.

Most of it is simple to understand but there is something I don't get, why does this work

Code: Select all

mov QWORD [QWORD _MM_PhysBitmap], rax
but this not

Code: Select all

mov qword [QWORD _MM_PhysSuperBitmap], r8
(this is from my memory manager, _MM_PhysBitmap and _MM_PhysSuperBitmap are both address symbols defined in the same file, but in .data)

The second code segment fails to compile in YASM with the error

Code: Select all

error: invalid combination of opcode and operands
and in nasm it seems to compile as a 32-bit address and LD quits saying

Code: Select all

relocation truncated to fit: R_X86_64_32 against `.data'
Does anyone know why this happens?
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
Zenith
Member
Member
Posts: 224
Joined: Tue Apr 10, 2007 4:42 pm

Re: 64-Bit Assembler Addressing

Post by Zenith »

About the toolchain, IIRC then all you need to do is to cross-compile binutils and gcc to the x86_64-elf target...

The problem might be that you're not specifying to assemble to a 64-bit binary. NASM has supported x86-64 instructions since version 0.99, and both assemblers should have a command line option to create an elf64 binary. If you're compiling to a flat executable, then the [BITS 64] directive might also be useful.
"Sufficiently advanced stupidity is indistinguishable from malice."
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: 64-Bit Assembler Addressing

Post by thepowersgang »

For the toolchain I did cross-compile binutils using the Wiki tutorial but only got LD.

As for telling them to use 64-bits I have. In all my source files I have included [BITS 64] at the beginning of the file.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: 64-Bit Assembler Addressing

Post by 01000101 »

you need to compile all of your 64-bit NASM files with the command line arg "-f elf64", and then link them all together using LD with the args "-m elf_x86_64 --oformat binary" included. This will result in a 64-bit binary.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: 64-Bit Assembler Addressing

Post by thepowersgang »

What I get is a 64-bit binary, with access to R-registers, but absolute memory accesses don't seem to work to registers other than rax (I think, I know that to/from r8, rsi, and rdi do not work while to/from RAX does)

Using the same linking process I can run and access 64-bit code and data in bochs, just the memory access does not compile properly (And I have been compiling in NASM with -felf64)
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
JohnnyTheDon
Member
Member
Posts: 524
Joined: Sun Nov 09, 2008 2:55 am
Location: Pennsylvania, USA

Re: 64-Bit Assembler Addressing

Post by JohnnyTheDon »

What I get is a 64-bit binary, with access to R-registers, but absolute memory accesses don't seem to work to registers other than rax (I think, I know that to/from r8, rsi, and rdi do not work while to/from RAX does
O.o Thats certaintly weird. You are switching into long mode right? How does your startup code work (your own bootloader, grub, etc.) ?
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: 64-Bit Assembler Addressing

Post by thepowersgang »

I'm using a 32-bit stub that's loaded by GRUB to 2Mb and that then parses the kernel Elf64 file which is passed as a module by GRUB.

I think the problem is that there might be a restriction on the source/destination registers for qword operations but I can't find any indication of that on the 'net and from my expirence with 16/32-bit operations there shouldn't be any.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Re: 64-Bit Assembler Addressing

Post by 01000101 »

It kinda sounds like your GDT's bit-width (not the correct term, but it's close) bit is set to 32-bits and not 16-bits (which it needs to be for 64-bit operations).

Does bochs debugger (the log output version) give you some lines like this:

Code: Select all

00031471612i[CPU0 ] CPU is in long mode (halted)
00031471612i[CPU0 ] CS.d_b = 16 bit
00031471612i[CPU0 ] SS.d_b = 16 bit
If either one of those are 32, or if the long mode bit in MSR 0xC0000080 are not set, you are somehow stuck in-between 32-bit PMode and 64-bit LMode. =)
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: 64-Bit Assembler Addressing

Post by thepowersgang »

I don't mean to be rude but I did say in my first post that the problem was at compile/link time. Yasm prints out an error on the memory access. If I take the extra lines of code to load the address into a register and then load the value it works perfectly, but AFIK you should not have to do that.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: 64-Bit Assembler Addressing

Post by Brendan »

Hi,
thepowersgang wrote:Does anyone know why this happens?
From the page about AMD64 in YASM's web site:
YASM wrote: Displacements

Just like immediates, displacements, for the most part, remain 32 bits and are sign extended prior to use. Again, the exception is one restricted form of the mov instruction: between the al/ax/eax/rax register and a 64-bit absolute address (no registers allowed in the effective address). In NASM syntax, use of the 64-bit absolute form requires [qword].
Basically, "mov qword [QWORD _MM_PhysSuperBitmap], r8" is an instruction the CPU doesn't support, and you'd need to either make sure that the label "_MM_PhysSuperBitmap" is a 32-bit (signed) address, or use RIP relative addressing (where there's a 32-bit signed displacement relative to RIP), or use RAX instead of R8, or do something like:

Code: Select all

    mov rbx,_MM_PhysSuperBitmap
    mov [rbx], r8
Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: 64-Bit Assembler Addressing

Post by thepowersgang »

Does anyone have a list of what instructions are valid to use 64-bit offsets for, because I can't seem to find any?
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: 64-Bit Assembler Addressing

Post by Love4Boobies »

How about you take a look through the Intel manuals and see for yourself? You don't really exepct us to look through volumes 2A and 2B for you and post each and every instruction here, do you?
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: 64-Bit Assembler Addressing

Post by thepowersgang »

I thought there might be a list of instructions somewhere that go against what seems to be possible with the structure of the x86-64 (REX prefix denoting extra registers/64-offsets), I'll see if my edition of the Intel manuals has anything on it as I've used every 32-bit GP register in my code and a total rewrite is not what I feel like just now. :D
Thanks though.


----- STRIKE THAT ------
It seems that the only register that can be used as a destination for Absolute memory addresses is RAX. :shock: (Vol. 2A 3-639 of Intel Manuals)
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Post Reply