About addressing in x64

Started by themaster, June 21, 2012, 12:28:35 AM

Previous topic - Next topic

themaster

Trying to write assembler x64 code. Found a problem:linker says
Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol 'hInstance'
about such code:

.data
hInstance dq ?
.code
main proc
        ...
mov rcx, hInstance ; ...

It is because some problems of addressing and writing parameters of 'mov' instruction.
I can use parameter  /LARGEADDRESSAWARE:NO, and error will disappear.
But how should I write instruction 'mov' and it's parameters, if I just want to get a value from memory and put it into general purpose register, in 'pure' x64, not using x32?
Something like this question was asked here:
http://forum.pellesc.de/index.php?topic=2920.msg11064
but forum recommended me to post a new topic, not reply in existing.

Greenhorn

Hi,

I don't know if it is the best solution, but you can do it like this:
lea rcx, hInstance
mov rcx, qword ptr [rcx]



Bitbeisser

You are looking in the wrong direction for your (non-)problem here I guess...

The problem is not to "write" this type of code, but rather that in "pure 64bit code", you have an address range larger than 2GB. As you state yourself, the error message is from the linker (not the assembler), which requires that you add the /LARGEADDRESSAWARE:NO parameter so that it (the linker) knows how to handle the relocation info for that particular assembler module...

Ralf

Greenhorn

If you set the option /LARGEADDRESSAWARE:NO your application can only handle addresses lower than 2GB.
As I understand the documentation right, this is not related to a particular (object-)module.
Please correct me if I'm wrong...

QuoteThe /LARGEADDRESSAWARE option tells the linker that the application can handle addresses larger than 2 gigabytes. In the 64-bit compilers, this option is enabled by default. In the 32-bit compilers, /LARGEADDRESSAWARE:NO is enabled if /LARGEADDRESSAWARE is not otherwise specified on the linker line.

If an application was linked with /LARGEADDRESSAWARE, DUMPBIN /HEADERS will display information to that effect.
http://msdn.microsoft.com/en-us/library/wz223b1z

If I remember it right, I had this problem only with external symbols/tables...

CommonTater

Quote from: Greenhorn on June 21, 2012, 07:52:16 PM
If you set the option /LARGEADDRESSAWARE:NO your application can only handle addresses lower than 2GB.

If you set the option /LARGEADDRESSAWARE:NO your 32 bit application can only handle addresses lower than 2GB.

64 bit aps suffer no such limitation but all addressing is done with 64bit registers.

Greenhorn


CommonTater

Quote from: Greenhorn on June 21, 2012, 10:33:24 PM
Quote from: CommonTater on June 21, 2012, 09:00:34 PM
64 bit aps suffer no such limitation ...
Yes, unless you specify /LARGEADDRESSAWARE:NO ...

http://msdn.microsoft.com/en-us/library/aa384271%28VS.85%29.aspx

Strange... Live and learn, I guess... thanks for the link.

themaster

#7
Quote from: Greenhorn on June 21, 2012, 04:50:06 PM
I don't know if it is the best solution, but you can do it like this:
lea rcx, hInstance
mov rcx, qword ptr [rcx]

Just tested. Instruction

lea rcx, hInstance

also is cause of linker's clause, "Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol...".
May be I should write some another form of this instruction? Or I can change other linker's parameters?
What is interesting: I wrote the same "hello world" application by C and read disassembly. There is another string and no linker clause:

lea rcx, [hInstance]

Square brackets added. But in assembler file clause presents, at both variants, with brackets and without them.

Greenhorn

Maybe it is more helpful if you could post the whole ASM code and the console output ...
Or better attach the whole project files.

Greenhorn

Quote from: CommonTater on June 21, 2012, 10:57:54 PM
Strange... Live and learn, I guess...
This comes daily in my mind, too...  :D

themaster

#10
I made example project and wrote in it some of my problems. It assembles without errors if parameter -largeaddressaware:no setted. What should I change to assemble it with large addresses switched on?
Also, I can not use floating point instructions. I wrote it in comments of code. I will be very thankful if somebody has some ideas about it. Code is:

; another problem: I can not load '1' into math coprocessor register - solved.
finit

        fldz ; I should add it here. FPU stack is empty, so I can not add anything to empty register.

mov rax, 1
sub rsp, 28
push rax ; here '1' is at address [rsp]
fiadd dword ptr [rsp] ; but after here all registers of math coprocessor is still empty!
nop ; may be I forgot something?
nop


Greenhorn

Hi,

sorry for my late reply but I'm very busy in the moment...

I didn't took a look at your FPU code, sorry.

I took this line of code into the file:
mov rax, hInstance
As I expected, Ms link.exe is linking the file with no errors.

Maybe Pelle should take a look at it...


Pelle

Well, I tried the project in check.zip with my installed v7.00 RC4 (X64) and I see no error at all...
/Pelle

Greenhorn

Hi Pelle,

yes, that's right.
With Pelles C v7.00.350 (Win64) the code compiles and links fine without errors.
Even with the instruction mov rax, hInstance:)

In RC3 there was the error mentioned by the OP above.

So, everything works fine now...