NASM 64 Bit Not Liking My Variable

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

NASM 64 Bit Not Liking My Variable

Post by AJ »

Hi,

I'm trying to write a simple test-tick counter isr in NASM, and for some reason, it's not compiling. The sample is as follows:

Code: Select all

[BITS 64]

[global tickcount_isr]
tickcount_isr:
	push	rax
	
	mov	rax,	[__tickcount]
	inc	rax
	mov	[__tickcount],	rax
	
	pop		rax
iretq

__tickcount dq 0

...and the error message is 'relocation truncated to fit R_X86_64_32 against .text'. If I declare the variable in my C code instead, the error just changes to 'fit R_X86_64_32 against .bss', as you might expect.

The error appears twice - once for each time I move to/from rax and occurs whether or not I specify a qword move, or stick align 64 at the top of the source. I am compiling to elf64 and have lots of other .asm source which compiles nicely (although, come to think of it, nothing which attempts moving a variable's value to a 64 bit register).

Can anyone see what am I missing out?
Cheers,
Adam
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

The follow assembles successfully with yasm, perhaps it'll work for you? :)

Code: Select all

[BITS 64]

[global tickcount_isr]
[global __tickcount]
;[extern __tickcount]

[section .text]
tickcount_isr:
   push rax

   mov rax, [__tickcount]
   inc rax
   mov [__tickcount], rax

   pop rax
   iretq

[section .data]
__tickcount dq 0
Hope this helps 8)

EDIT: Use the elf64 object format, so nasm -f elf64 or yasm -f elf64.
Last edited by Brynet-Inc on Thu Jan 24, 2008 11:28 am, edited 1 time in total.
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Nope:

Code: Select all

source//arch/x86_64/interrupt/irq/tickcount.asm:(.text+0x5): relocation truncate
d to fit: R_X86_64_32 against `.data'
source//arch/x86_64/interrupt/irq/tickcount.asm:(.text+0x10): relocation truncat
ed to fit: R_X86_64_32 against `.data'
make: [bin/x86_64/kernel.sys] Error 1 (ignored)
cp: cannot stat `bin/x86_64/*.sys': No such file or directory
make: [install] Error 1 (ignored)
Copy and pasted error text after doing a copy and paste of your code :) . NASM version reports v2.00. Thanks for trying!
Adam
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

I accidentally trimmed the iretq instruction above, if that makes any difference..

The code pasted above does assemble successfully with yasm-6.1 and nasm-2.01.. what you're looking at is a GNU gcc/ld error.

Why don't you write the code in GNU assembler btw? :?

EDIT: Perhaps you should recompile everything with gcc -mcmodel=medium or -mcmodel=kernel ?
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Brynet-Inc wrote:The code pasted above does assemble successfully with yasm-6.1 and nasm-2.01.. what you're looking at is a GNU gcc/ld error.
Thanks - I'd blindly assumed it was an NASM error because my C++ modules were working fine. Oh - and it looks like although I'm using NASM 2, it's 2.00 which is a RC, so I'll upgrade and see if that makes a difference
Why don't you write the code in GNU assembler btw? :?
Point taken. I'm afraid it's for no better reason than "That's what I've always done". I'll look in to GNU assembler and definitely make the switch if it solves the problem.
EDIT: Perhaps you should recompile everything with gcc -mcmodel=medium or -mcmodel=kernel ?
I've never used these flags before, but when I have my main machine again tomorrow, I'll look up their full effects and play with adding one or other of them.

Thanks for the advice,
Adam
SpooK
Member
Member
Posts: 260
Joined: Sun Jun 18, 2006 7:21 pm

Post by SpooK »

AJ wrote:Oh - and it looks like although I'm using NASM 2, it's 2.00 which is a RC, so I'll upgrade and see if that makes a difference
NASM 2.00 is NASM 2.00. If it follows with RC X, where X is the release candidate number, then it is as such.
Brynet-Inc wrote: The code pasted above does assemble successfully with yasm-6.1 and nasm-2.01.. what you're looking at is a GNU gcc/ld error.
That should have been apparent from the original error message, but the error may be in how the variable is being addressed in NASM itself.

If he is able to assemble using "[BITS 64]", then there is no question that it is the 64-bit version of the object file format that he is using.

As for the code, first question is... why not use the following???

Code: Select all

[BITS 64]

[global tickcount_isr]
tickcount_isr:
   inc   QWORD[__tickcount]
iretq

__tickcount dq 0
Second is, are you linking things correctly against 64-bit versions of your C code?

Have you tried using explicit operand/address sizes, like the following???

Code: Select all

[BITS 64]

[global tickcount_isr]
tickcount_isr:
   push   rax
   
   mov   rax,   [QWORD __tickcount]
   inc   rax
   mov   [QWORD __tickcount],   rax
   
   pop      rax
iretq

__tickcount dq 0
The above code enforces 64-bit address sizes and may help you to draw closer to the real issue.

HtH ;)
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

SpooK wrote:NASM 2.00 is NASM 2.00. If it follows with RC X, where X is the release candidate number, then it is as such.
Sorry, I meant "as opposed to 2.01, which Brynet was using.
As for the code, first question is... why not use the following???
Because that gave the same error message originally, which is why I moved over to using RAX.
Second is, are you linking things correctly against 64-bit versions of your C code?
Yes - I'm using a custom 64 bit toolchain which works nicely for everything else.
Have you tried using explicit operand/address sizes, like the following???

...

The above code enforces 64-bit address sizes and may help you to draw closer to the real issue.
Wow - that worked! I've never put QWORD inside the brackets before, but I did that and the link error went away. I had certainly tried it with QWORD outside the brackets. I guess the difference is that one ensures a 64 bit pointer, whereas the other just refers to a 64 bit operand with a pointer of any size.

Thanks for the help,
Adam
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

SpooK wrote: As for the code, first question is... why not use the following???
I know this isn't AJ's reason, but the reason *I* sometimes mov to a reg, do an INC, mov back -- is so I can conveniently watch the value change in bochs, with just an "r" command.
SpooK
Member
Member
Posts: 260
Joined: Sun Jun 18, 2006 7:21 pm

Post by SpooK »

AJ wrote:Wow - that worked! I've never put QWORD inside the brackets before, but I did that and the link error went away. I had certainly tried it with QWORD outside the brackets. I guess the difference is that one ensures a 64 bit pointer, whereas the other just refers to a 64 bit operand with a pointer of any size.
Precisely, except that non-explicit operations refer to the default size, in which tends to be instruction specific but mostly seems to revolve around 32-bit even in Long Mode ;)
AJ wrote: Thanks for the help,
Adam
np.
Post Reply