Page 1 of 1

Bitness of control transfer instructions in 64-bit mode

Posted: Fri May 17, 2024 4:35 am
by awik
Hi all,

I'm confused about the address size of control transfers in 64-bit mode.

The Intel "Software Developer's Manual", vol.1, section 7.3.8.3, reads:
In 64-bit mode, the operand size for all near branches (CALL, RET, JCC, JCXZ, JMP, and LOOP) is forced to 64 bits.
However, below in the same section, it reads:
Note that the displacement field for relative branches is still limited to 32 bits and the address size for near branches is not forced.
Which one is it, or am I overlooking or misinterpreting some detail?

Regards,
Albert.

Re: Bitness of control transfer instructions in 64-bit mode

Posted: Fri May 17, 2024 8:53 am
by nullplan
Yeah, it's confusing. All relative branches do have a 32-bit signed displacement. I think by "64-bit operand size", they mean that that displacement will be added to RIP, not EIP (and stored back into RIP). So you have all possible virtual addresses to run at, but can only branch 2GB in any direction at any time. The only instruction I know that can actually take a 64-bit immediate operand is "mov". So if you need to branch further than 2GB, you can use mov to load the 64-bit destination address into a register, then jump indirectly to the register. You can also branch indirectly to memory, and then the memory operand can be 64-bit.

Re: Bitness of control transfer instructions in 64-bit mode

Posted: Fri May 17, 2024 12:13 pm
by Octocontrabass
"Operand size" doesn't actually refer to the size of the instruction's operand, it's an instruction attribute that controls the size of the operation performed by that instruction. For example, you can have an arithmetic instruction like "add ecx, 32" that has a 32-bit operand size, but the immediate operand could be an 8-bit value that gets sign-extended to 32 bits. When AMD added the 64-bit operand size attribute, they decided that immediate operands would stay 32-bit and use sign extension. (Except MOV, which can have a 64-bit immediate operand.)

There are some instructions, like LGDT, where the operand size attribute is different from the size of the operand.

Re: Bitness of control transfer instructions in 64-bit mode

Posted: Sat May 18, 2024 7:29 am
by awik
So maybe forced 64-bit operand size just means the instructions (near branches) operate on the 64-bit RIP?

And address size not being forced to 64 bits means the instruction operands don't have to be 64-bit?

That would make sense.

Re: Bitness of control transfer instructions in 64-bit mode

Posted: Sat May 18, 2024 11:55 am
by Octocontrabass
awik wrote:So maybe forced 64-bit operand size just means the instructions (near branches) operate on the 64-bit RIP?
It means they always operate on RIP. Unlike other instructions, where you can choose 16-bit, 32-bit, or 64-bit operand size, near branches only allow 64-bit operand size. (Actually, AMD CPUs allow near branches with 16-bit operand size...)
awik wrote:And address size not being forced to 64 bits means the instruction operands don't have to be 64-bit?
No, address size refers to the effective address calculation for memory operands. Address size not being forced to 64-bit means you can choose between a 32-bit or a 64-bit effective address for a memory operand. Only CALL and JMP allow memory operands.