How may I create a far pointer using NASM?

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
pepito

How may I create a far pointer using NASM?

Post by pepito »

Some of my system services need a 'far pointer' (lineal address) to be passed as argument. Where this 'far pointer' is an offset above address 0.

I want to know, how can I make this 'far pointer' using NASM or DJGPP code?

I tried using LEA instruction (NASM) and '&' operator (DJGPP), but both return the offset above the begining of the code not above address 0.

Thank you,

pepito
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

RE:How may I create a far pointer using NASM?

Post by gaf »

Hi pepito,
you have to add your code-segemnt's offset to the eip

; load the linear address of test to eax
mov ax,cs
shl eax,4     ; multiply it with 16
add eax,test

test:
hlt


bye,
Daniel Raffler
pepito

RE:How may I create a far pointer using NASM?

Post by pepito »

Thank you, but not...

I forgot to say that my code runs in protected mode, then the CS register have a selector and not an address.
CodeSlasher

RE:How may I create a far pointer using NASM?

Post by CodeSlasher »

If you are using FLAT memory model, then there are no FAR pointer because 32bits is enough to cover any address you need in the 4Gb address space.
If you are usign a Segmented model in protected mode, note that you will need to use something like this

far_pointer: dw 0     ;this is the selector number
             dd 0     ;this is the offset in the segment

I'm not entirely sure thats correct but a browse of the Intel docs should clarify it.
mindvnas

RE:How may I create a far pointer using NASM?

Post by mindvnas »

actually, the offset and segment is swapped, like this:
far_ptr: dd ? ; offset
         dw ? ; selector; maybe this is also a dword.
CodeSlasher

RE:How may I create a far pointer using NASM?

Post by CodeSlasher »

Yeah,I thought so too. A Selector is a is 16bits so its a dword.
CodeSlasher

RE:How may I create a far pointer using NASM?

Post by CodeSlasher »

Sorry,I meant WORD!:(
16bits -> WORD  -> DW
32bits -> DWORD -> DD
pepito

RE:How may I create a far pointer using NASM?

Post by pepito »

Thank you very much to every one!
Schol-R-LEA

RE:How may I create a far pointer using NASM?

Post by Schol-R-LEA »

Except that Pepito said he wanted to pass it as an argument, presumably to a C function. In which case:

   mov  EAX, DWORD [foo]     ; push the offset first, so that
   push EAX                  ; it is in the higher address
   xor  EAX, EAX             ; clear the upper half of EAX
   mov  AX,  WORD  [foo + 4] ; get the selector for
   push EAX                  ; push the 16-bit selector value
   call bar                  ; call the function it is being passed to

  ...
foo: dd 0                    ; offset for pointer foo  
     dw 0                    ; selector for pointer foo

Keep in mind, though, in the C calling convention, arguments are pushed in reverse order; so if the call is to a C function whose prototype is

void bar (char baz, char* quux, double zot)

then you would have to first push the the two parts of zot (IEE double-precision float == 64-bit == two doublewords), then push quux as described above, then clear EAX again and push the one byte of baz.

HTH. Comments and Corrections Welcome.
CodeSlasher

RE:How may I create a far pointer using NASM?

Post by CodeSlasher »

Yeah Very true and correct,excep that in 32bit mode the stack is 32bits so even CHARs are pushed as double words(dwords) so for the char baz,he'll have to also do
... ;same things as above
...
...
xor eax,eax
mov al,byte _baz  ;underscore infront of c variables when accessed from asm
push eax
call _bar
Schol-R-LEA

RE:How may I create a far pointer using NASM?

Post by Schol-R-LEA »

Oh, I understood that; in fact, that was the point I was trying to get across, that you'd need to clear EAX in order to push the one byte, since you were actually pushing EAX and not just AL. Even in real mode, you can't push a single byte. Apparently I didn't make that as clear as I'd meant. Sorry about that.
Post Reply