Page 1 of 1

yasm 64-bit uses 32bit pointers !!

Posted: Wed Jun 04, 2008 3:34 pm
by HJED
hi
I am trying to link 64-bit code with the windows x64 linker v9.00.21022.08
and yasm however yasm appears to be using 32bit pointers for external variables and the linker doesn't like this.

the only way to make yasm do 64-bit pointers is to have qword proseding the symbol in every use of it
e.g

Code: Select all

mov rax, qword a
add rdx, a
makes the symbol a 32-bit address
whilst
mov rax, qword a
add rdx, qword a
makes it a 64-bit address
there are some instructions where it is not possible to do this
is there a way around this?

normally I wouldn't care but my linker throws errors
start.obj : error LNK2017: 'ADDR32' relocation to 'idtp' invalid without /LARGEADDRESSAWARE:NO
start.obj : error LNK2017: 'ADDR32' relocation to 'aportid' invalid without /LARGEADDRESSAWARE:NO
start.obj : error LNK2017: 'ADDR32' relocation to 'aportid' invalid without /LARGEADDRESSAWARE:NO
i tried using /LARGEADDRESSAWARE:NO but it is not suported with /driver which I read is required for OS dev

it only complains about the symbols that dumpbin says are in the relocation section and are of type ADDR32
the ones that are of type ADDR64 have qword proseding them in every reference in the overs it is not possible for me to do that

Code: Select all

RELOCATIONS #1
                                                Symbol    Symbol
 Offset    Type              Applied To         Index     Name
 --------  ----------------  -----------------  --------  ------
 00000002  ADDR64            00000000 00000000         5  System_get_New_Stack
 0000000D  REL32                      00000000         8  main
 00000013  ADDR64            00000000 00000000         4  System_get_New_Address

 0000001D  ADDR64            00000000 00000000         B  idtp
 0000002A  ADDR32                     00000000         B  idtp
 00000150  ADDR64            00000000 00000000        2D  fault_handler
 00000178  ADDR32                     00000000        2E  aportid
 0000017F  ADDR64            00000000 00000000        2F  res
 00000189  ADDR64            00000000 00000000        31  avalue
 00000195  ADDR32                     00000000        2E  aportid

the above code is form a dumpbin of my asm code before it is linked

i have also noticed when i pt qword before it in some uses and not others it says it is both 64bit and 32bit!

if anyone could tell me how to fix this i would be very great full
thanks for any help :?:

PS my yasm command line is

Code: Select all

yasm -Xvc -f win64 -m amd64 --force-strict  -o \intermediate\start.obj -rnasm -pnasm  start.asm

Posted: Wed Jun 04, 2008 4:30 pm
by Korona
The x86-64 instruction set does not support 64 bit operands for every instruction. Only the mov instruction and a few other instructions (?) support 64 bit immediate operands.
add rax, qword address is not even a valid instruction. It will be assembled to something like add rax, dword address. (REX.W + ADD)

Posted: Wed Jun 04, 2008 4:45 pm
by HJED
then how do you stop the errors the linker throws?
i tiried using nasm 2.0 on the same code and the linker said every single symbol and method in the code was unrefrenced.

so if anyone knows how to make yasm work with the microsoft linker please tell me

Posted: Wed Jun 04, 2008 11:56 pm
by jnc100
The problem is exactly as Korona says: there is no 'add rax, imm64' instruction in the x86_64 instruction set, i.e. you cannot add a 64-bit immediate operand to a register (when using the address of a symbol in an instruction, the immediate form is used and a zero field is put in as the immediate value which is replaced by the actual address during the link phase, assuming rela relocations).

You need to load the 64-bit value to another register, e.g.

Code: Select all

mov rdx, a
... or ...
lea rdx, [a]

add rax, rdx
Its not a problem with the linker: you'll get similar errors with ld.

Regards,
John.

Posted: Thu Jun 05, 2008 3:48 am
by HJED
i was just giving that code as an example of my problem i don't use the above code.

there would be the same affect with

dose not work:

Code: Select all

mov rax, qword a
mov rdx, a 
and
works:

Code: Select all

 mov rax, qword a
mov rdx, qword a
I used add as an example because I wanted to be clear it wasn't a problem with just one operand.

but as you just said I can't always add qword to every reference of a symbol

sorry for the confusion but without putting qword in add I still get the same errors.

these error appears to be caused because yasm is giving symbols 32-bit addresses when the linker wants 64-bit addresses and adding qword before every use of the symbol (which is not always) is the only way to fix this.

what i am asking is how to fix this so I don't have to put qword in front of every use of every external symbol
thanks for any help

Posted: Fri Jun 06, 2008 11:01 am
by jnc100
As far as yasm is concerned, 'a' is a symbol. It has a value. Yasm has no knowledge as to whether it is an address at all, and as the default operand size on x86_64 is 32 bits, then doing mov rax, a by default implies a 32-bit move of the value of a to rax. If you want to treat is as 64-bit then you have to use the qword override. Alternatively you could treat it as an address and do lea rax, [a] and let yasm choose an appropriate addressing mode and relocation type.

Regards,
John.