0

I'm trying to code an OS and every thing went well until here. I'm in Long-Mode and my 'kernel' code is executing if I pagemap it to an address that's 32-Bit. But if i don't do that my kernel stops working. In the end I found out that my compiler (NASM 2.15.05) compiles all addresses in a mov instruction as a 32-Bit val not a 64-bit val. I use

nasm test.asm -f bin -o test.bin

to compile my code. So my question is how do I get it to work so it compiles 64-bit addresses as 64-bit not 32-bit ?

[org 0x100000000]
[bits 64]


;this does not work
mov rax, [l1]
;nasm bin output = 48 8b 02 25 | 1c 00 00 00 | <--- this is the addr (32-bit)


;this works
mov rbx, l1
mov rax, [l1]

jmp $

l1:     dq 0x1234
  • 1
    Issue a `default rel` directive. – fuz Mar 19 '22 at 15:27
  • You claim that `mov rax, [l1]` works after an unrelated `mov rbx, l1` but not before? That makes no sense, that's the same instruction as before. x86-64 only supports 64-bit *absolute* addressing modes for mov to/from AL/[ER]AX, the "moffs" forms of mov (https://www.felixcloutier.com/x86/mov), but that's inefficient vs. RIP-relative or even the less efficient 32-bit absolute. – Peter Cordes Mar 19 '22 at 15:48
  • I don't know if there is an exact duplicate that explains the entire issue using NASM syntax, but some related questions are: https://stackoverflow.com/questions/31234395/why-use-rip-relative-addressing-in-nasm/36952302#36952302, https://stackoverflow.com/questions/43367427/32-bit-absolute-addresses-no-longer-allowed-in-x86-64-linux, https://stackoverflow.com/questions/56262889/why-are-global-variables-in-x86-64-accessed-relative-to-the-instruction-pointer – Nate Eldredge Mar 19 '22 at 15:49
  • The short answer is that it's not NASM's fault - the instruction set is more limited than you think. x86-64 has very limited support for 64-bit absolute addresses and they are not allowed in most instructions. You are expected to either locate all your code and static data in the low 4GB of virtual memory, so that 32-bit absolute addresses work, or else use RIP-relative addressing with 32-bit displacements, which lets you put your code and static data anywhere in memory so long as it is all within 2 GB of each other. – Nate Eldredge Mar 19 '22 at 15:52
  • @NateEldredge: Your last 2 links are the same link twice, but yeah probably a duplicate of something if the querent explained what they actually wanted. There's probably a Q&A somewhere explaining how to use `[strict qword l1]` to get the moffs encoding in case that's relevant. – Peter Cordes Mar 19 '22 at 15:52
  • @PeterCordes: Thanks, copy and pasting from too many tabs. – Nate Eldredge Mar 19 '22 at 15:52
  • Thx i didn't knew that they where so limited and just thought it would work – user1237916231 Mar 19 '22 at 15:54

0 Answers0