64-bit retf with NASM

Programming, for all ages and all languages.
Post Reply
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

64-bit retf with NASM

Post by bluemoon »

I noticed that nasm do not generate the REX.w prefix with 64-bit retf

For example, I have this code within BITS 64 section:

Code: Select all

    mov     rdi, gdtr
    lgdt    [rdi]

    mov     ax, SEG_DATA64_0
    mov     ds, ax
    mov     es, ax
    mov     fs, ax
    mov     gs, ax
    mov     ss, ax
    mov     rsp, kstack_end
    push    qword 2
    popf

    mov     rcx, qword .reloadcs
;    jmp     rcx

    push    qword SEG_CODE64_0
    push    rcx
    db 0x48
    retf
As you can see, I need to hand code the prefix. Is it a bug in nasm or do I suppose to manually type the prefix whenever needed? I'm new to all these REX stuff.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: 64-bit retf with NASM

Post by bluemoon »

Oh I see that NASM manual said "yasm insert REX automatically", but I guess nasm itself do not, or it might not in 2.09.10 which I'm using.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: 64-bit retf with NASM

Post by Brendan »

Hi,
bluemoon wrote:As you can see, I need to hand code the prefix. Is it a bug in nasm or do I suppose to manually type the prefix whenever needed? I'm new to all these REX stuff.
For normal 64-bit code (where everything is "flat"), there's no reason to use far calls and far returns, except for returning to 16-bit or 32-bit code. For rare cases (like shifting to a different GDT where CS uses a different descriptor number) you'd have to use "a64 retf".


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: 64-bit retf with NASM

Post by bluemoon »

a64 has no effect. The output from nasm for "a64 retf" is:

Code: Select all

ffffffff801010af:	6a 20                	pushq  $0x20
ffffffff801010b1:	57                   	push   %rdi
ffffffff801010b2:	cb                   	lret
I still need to manually code that 0x48. But I got your point, retf with operand size=64 is rare case.
Gigasoft
Member
Member
Posts: 855
Joined: Sat Nov 21, 2009 5:11 pm

Re: 64-bit retf with NASM

Post by Gigasoft »

Brendan wrote:For normal 64-bit code (where everything is "flat"), there's no reason to use far calls and far returns, except for returning to 16-bit or 32-bit code.
Or it could be a return to user mode.
Rudster816
Member
Member
Posts: 141
Joined: Thu Jun 17, 2010 2:36 am

Re: 64-bit retf with NASM

Post by Rudster816 »

According to the Intel Manual:
In 64-bit mode, the default operation size of this instruction is the stack-address size, i.e. 64 bits.
I'm not 100% sure, but from the sounds of that, it doesn't look like you need a REX prefix.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: 64-bit retf with NASM

Post by gerryg400 »

Rudster816 wrote:According to the Intel Manual:
In 64-bit mode, the default operation size of this instruction is the stack-address size, i.e. 64 bits.
I'm not 100% sure, but from the sounds of that, it doesn't look like you need a REX prefix.
Yes it's not needed. IRET on the other hand does need REX.
If a trainstation is where trains stop, what is a workstation ?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: 64-bit retf with NASM

Post by bluemoon »

However, someone also wrote on the wiki: X86-64_Instruction_Encoding
1: The following instructions default to (or are fixed at) 64-bit operands and do not need the REX prefix for this: CALL (near), ENTER, Jcc, JrCXZ, JMP (near), LEAVE, LGDT, LIDT, LLDT, LOOP, LOOPcc, LTR, MOV CR(n), MOV DR(n), POP reg/mem, POP reg, POP FS, POP GS, POPFQ, PUSH imm8, PUSH imm32, PUSH reg/mem,
PUSH reg, PUSH FS, PUSH GS, PUSHFQ and RET (near).
I suppose the RET(near) is implying RETF is not default to 64-bit. Anyway, REX.w = 1 is needed in my case to explicitly set to use 64-bit operands.
btw, yasm does generate REX for this automatically. berkus is right, I should switch to yasm.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: 64-bit retf with NASM

Post by gerryg400 »

bluemoon wrote:I suppose the RET(near) is implying RETF is not default to 64-bit. Anyway, REX.w = 1 is needed in my case to explicitly set to use 64-bit operands.
btw, yasm does generate REX for this automatically. berkus is right, I should switch to yasm.
A few years ago someone on the list (I think it was Owen) tested some machines and found that FAR CALL in 64bit mode only works on Intel machines. It does not work on AMD machines. The Intel docs imply that it works while the AMD docs say that it doesn't work. So the docs are reasonably 'correct'.

There is a good chance that the same applies to FAR RET.

I think care is needed here and you may find that you code does not work on all machines. To be sure you really should use the documented method which is to use an IRET.
If a trainstation is where trains stop, what is a workstation ?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: 64-bit retf with NASM

Post by bluemoon »

OK Thanks for the advice.

EDIT: I got the iret worked. The sad news is that nasm 2.09 does not emit REX for iret as well (and yasm does emit REX, for the same code).
EDIT2: IRETQ does the tricks. Time for me to re-read the assembler manual for 64-bit stuff.
Last edited by bluemoon on Fri Apr 27, 2012 7:29 pm, edited 1 time in total.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: 64-bit retf with NASM

Post by gerryg400 »

Bluemoon, I found the thread. Actually it seems that Owen did try FAR RET and it worked. I would still be cautious though. IRET is the documented method and will always work.

http://forum.osdev.org/viewtopic.php?f= ... 51&start=0
If a trainstation is where trains stop, what is a workstation ?
Post Reply