NASM Forum > Using NASM

How does linker know the location of the function?

(1/2) > >>


I am new to NASM (I used to program on FASM) and currently on the stage of careful manual reading. However there is some point that is not clear. Creating application in FASM I need to tell the assembler in which dll my function is stored. Doesn't matter if I created this dll myself or it isprovided by OS. 

On the opposite side looking at examples like
I've noticed that there is no such information in the code or no other files where such information might be provided. Perhaps I'm missing something

How does it work?

I have never created a multi file assembler project, but I can tell you that the assembler only needs to know which routines are in external files, and the linker needs to know which library files to find external routines in. That seems to be what your link shows. I can't speak for how other assemblers declare the same routines.

How about the casewhen two dll have functions with identical names? Is it strictly forbidden?

According to the Manual (section 8.4.4) there is "import" directive which specifies the location of the functions in libraries. It is pretty much the same as FASM has except order of argument difference.

Each time you compile a source code to an object file is assigned a "virtual address" (a "relative" address) to each memory reference in your code. Example:

--- Code: ---bits 32

section .data

x:  dd  0

section .text

  global f
  inc dword [x]
--- End code ---
If you compile this you'll get:

--- Code: ---$ nasm -l test.lst test.asm
$ cat test.lst
 1                          bits 32
 3                          section .data
 5 00000000 00000000        x: dd 0
 7                          section .text
 9                            global f
10                          f:
11 00000000 FF05[00000000]    inc dword [x]
12 00000006 C3                ret
--- End code ---
Notice `x` get the offset 0 in `.data`section. and `f` got offset 0 on `.text` section. (and the offset in inc instruction is [00000000]).

When the linker is used with multiple modules it atributes different offsets to these references... Let's say you have another module (test2.asm) defining `y` as DWORD... to that object file `y` will get the offset 0 as well, but the linker puts `x` and `y` in the same section, assignining a different offsets for these 2 symbols.. The same to function's entrypoints...

Notice, also, that CALL/JMP and conditional jumps use relative addressing (relative to EIP ou RIP)...

In the case of DLLs, when they are loaded, the offset is avaliable in PE file format. In Windows, when you use GetProcAddress you get this address and assign to a function pointer to do an indirect call (late binding). Or the linker do this for you (early binding).

As for DLLs with functions with the same name, in early binding it can be problematic, but with late biding it has no problem, since the same is used only to find the address where the function is...

Many thanks for answers. Please correct me if I am wrong. Using some sort of PE Explorer I can look through all the functions that one can call from DLL and linker goes through this information and replaces my labels in Object file with actual offsets from PE headers in DLL.

Looking at disassembled code I've never seen usage of "LoadLibrary" and "GetProcAddress" (except 'wglGetProcAddress" but it is completely different story) is this because in majority of cases early binding was chosen?


[0] Message Index

[#] Next page

Go to full version