Page 1 of 1
64-bit retf with NASM
Posted: Thu Apr 26, 2012 8:38 am
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.
Re: 64-bit retf with NASM
Posted: Thu Apr 26, 2012 8:45 am
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.
Re: 64-bit retf with NASM
Posted: Thu Apr 26, 2012 9:34 am
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
Re: 64-bit retf with NASM
Posted: Thu Apr 26, 2012 9:43 am
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.
Re: 64-bit retf with NASM
Posted: Thu Apr 26, 2012 10:05 am
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.
Re: 64-bit retf with NASM
Posted: Thu Apr 26, 2012 7:51 pm
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.
Re: 64-bit retf with NASM
Posted: Thu Apr 26, 2012 8:26 pm
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.
Re: 64-bit retf with NASM
Posted: Fri Apr 27, 2012 6:27 pm
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.
Re: 64-bit retf with NASM
Posted: Fri Apr 27, 2012 6:48 pm
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.
Re: 64-bit retf with NASM
Posted: Fri Apr 27, 2012 7:08 pm
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.
Re: 64-bit retf with NASM
Posted: Fri Apr 27, 2012 7:22 pm
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