Author Topic: Absolute or Relative Addressing  (Read 17364 times)

Offline sal55

  • Jr. Member
  • *
  • Posts: 18
Absolute or Relative Addressing
« on: September 10, 2017, 02:53:59 PM »
Take code like this for x64:
Code: [Select]
    segment .data
abc:
    dq 0
    segment .text
    mov rax,[abc]
This has worked fine up to now. But I've has to switch to 'large address aware' on executables, to be able to address beyond 2GB. Then this crashed, and I was told the fix was to use 'default rel'.

This worked for that example. But not for this one:
Code: [Select]
    mov [rax*8+abc-8], rdx
This works in normal non-large-address mode and without using 'default'. The linker I'm using (GoLink) apparently loads the program beyond 4GB and the address of 'abc' will presumably require more than 32 bits to express.

Is that the problem here, that this address mode can't accommodate address fields more than 32-bits? If so, what's the answer?

(I don't fancy rewriting my code generators to take account of this; I just want to be able to allocate more than 2GB of dynamic memory, and make use of 64-bit pointers which I thought I could already do.)

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Absolute or Relative Addressing
« Reply #1 on: September 11, 2017, 06:11:35 PM »
The content of RAX is 0 due to "mov rax,[abc]"
That will generate an invalid / faulty address in "mov rax,[0 + abc -8],rdx" because abc-8 will read a protected area from outside the low boundary of the .data section.

------------------------------
data section high boundary
...
...
data section low boundary = abc
------------------------------
abc-8 is here in uncharted territory

Offline sal55

  • Jr. Member
  • *
  • Posts: 18
Re: Absolute or Relative Addressing
« Reply #2 on: September 12, 2017, 11:01:00 AM »
The content of RAX is 0 due to "mov rax,[abc]"
OK, but those are just unrelated fragments of code.

The instruction with [rax*8+abc-8] is taken from a separate code sequence that works perfectly fine in ABS mode in a non-large-address-aware executable. (Otherwise RAX would be zero in any operating mode.)

I'll have to look at instruction codings to see the size of the abc field (actually, abc-8) in [rax*8+abc-8] is 32- or 64-bit. If 32-bit, then I can see there is going to be a problem if the program is loaded high (above 4GB) and abc requires more than 32 bits to access.

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Absolute or Relative Addressing
« Reply #3 on: September 13, 2017, 05:05:53 AM »
Ok.

It's hard to tell then because I don't know RAX is pointing to where and how you arrange your data. But if indeed your "abc" is the first line, then "abc-8" will point to an address past the lower boundary.


Offline sal55

  • Jr. Member
  • *
  • Posts: 18
Re: Absolute or Relative Addressing
« Reply #4 on: September 22, 2017, 02:52:16 PM »
It seems that the problem is indeed due to address displacements being wider than 32 bits (due to the Golink linker loading the program at 0x1400000 I think it was).

The simple solution apparently is to tell it to load it at 0x400000! (Why it loads at 0x1400000 is not clear.)

However Golink has some other issues (it makes my executables look like they have a virus so harder to copy or share them, and sometimes slows down execution). I'm now using ld, but that has its own bugs with certain imports especially on Windows 10 where I can't use it at all. That leaves gcc (using ld via gcc) as a last resort, which is unsatisfactory (it adds in all sorts of libraries I don't want).

What do other people use as a linker for Windows 64-bit?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Absolute or Relative Addressing
« Reply #5 on: September 22, 2017, 04:05:16 PM »
Hi sal55,

Windows is above my pay grade, but in Linux we can tell gcc "-nostartfiles -nostdlibraries -f no-builtin"... I'm not sure I've got 'em all... You should be able to get gcc to invoke ld without linking in libraries you don't want. Of course, you should be able to invoke ld yourself, too. Unfortunately I don't know the correct command line. Can you give gcc the "-v" switch and see what it's telling ld? Courage!

Best,
Frank


Offline sal55

  • Jr. Member
  • *
  • Posts: 18
Re: Absolute or Relative Addressing
« Reply #6 on: September 22, 2017, 05:12:05 PM »
OK, I'll give that a go. Although it's possible that it is all those extras that inhibit the weird errors that ld.exe sometimes gives.

Not sure about gcc -v; to find out exactly what gcc was feeding ld.exe, I once replaced the latter with a program that just printed out its parameters. The results (only including one of my .obj files) are shown below. This is why I favoured the simpler linker, and why I'll probably be forced to write my own at some point.

0: c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe
1: -plugin
2: c:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/5.1.0/liblto_plugin-0.dll
3: -plugin-opt=c:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/5.1.0/lto-wrapper.exe
4: -plugin-opt=-fresolution=C:\Users\user\AppData\Local\Temp\ccpZKXHG.res
5: -plugin-opt=-pass-through=-lmingw32
6: -plugin-opt=-pass-through=-lgcc
7: -plugin-opt=-pass-through=-lmoldname
8: -plugin-opt=-pass-through=-lmingwex
9: -plugin-opt=-pass-through=-lmsvcrt
10: -plugin-opt=-pass-through=-lpthread
11: -plugin-opt=-pass-through=-ladvapi32
12: -plugin-opt=-pass-through=-lshell32
13: -plugin-opt=-pass-through=-luser32
14: -plugin-opt=-pass-through=-lkernel32
15: -plugin-opt=-pass-through=-lmingw32
16: -plugin-opt=-pass-through=-lgcc
17: -plugin-opt=-pass-through=-lmoldname
18: -plugin-opt=-pass-through=-lmingwex
19: -plugin-opt=-pass-through=-lmsvcrt
20: -m
21: i386pep
22: --exclude-libs=libpthread.a
23: -Bdynamic
24: -o
25: pc.exe
26: c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o
27: c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/crtbegin.o
28: -Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0
29: -Lc:/tdm/bin/../lib/gcc
30: -Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/lib/../lib
31: -Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../lib
32: -Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/lib
33: -Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../..
34: pc_start.obj
35: -lmingw32
36: -lgcc
37: -lmoldname
38: -lmingwex
39: -lmsvcrt
40: -lpthread
41: -ladvapi32
42: -lshell32
43: -luser32
44: -lkernel32
45: -lmingw32
46: -lgcc
47: -lmoldname
48: -lmingwex
49: -lmsvcrt
50: c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/crtend.o