"objdump -d" produces the following disassembly for x86-64 and shows this "jb" as taking a 2-byte jump offset: 400515: 66 0f 82 00 00 jb 51a 40051a: eb 02 jmp 40051e This is correct for 32-bit mode, but in 64-bit mode this "jb" should take a 4-byte jump offset. I'm not sure where that CPU behaviour is documented (I find the AMD manuals unclear on the matter), but the following test demonstrates it empirically: #include <stdio.h> asm(".global test\n" "test:\n" /* Clear the carry flag so that the following "jc" does not jump. */ "clc\n" /* "66 0f 82" is the encoding for "data16 jc". "jc" is also known as "jb". On x86-32, this takes a 2-byte operand, so it executes "jmp size2". On x86-64, this takes a 4-byte operand, so it executes "jmp size4". */ ".ascii \"\\x66\\x0f\\x82\\x00\\x00\"\n" /* We assume that this jump is encoded as a 2-byte instruction. */ "jmp size2\n" "jmp size4\n" "size2: jmp size_is_2\n" "size4: jmp size_is_4\n" ); void test(void); void size_is_2() { printf("operand size is 2 bytes\n"); } void size_is_4() { printf("operand size is 4 bytes\n"); } int main() { test(); return 0; } $ gcc test.c -o test -m32 && ./test operand size is 2 bytes $ gcc test.c -o test -m64 && ./test operand size is 4 bytes Since using the 66 prefix on direct jumps is not very useful on x86-64 -- it only increases the size of the encoding -- we wouldn't expect to see it very often.
AFAIK 66-prefixed branches are invalid on x86_64. When I looked into them about a year ago, I found that they also behaved very differently on Intel and AMD, so you really shouldn't be using them.
Yes, you're right. I was testing on an Intel machine. When I tested on an AMD machine, it produced: $ gcc test.c -o test -m64 && ./test operand size is 2 bytes It looks like Intel failed to copy AMD in this regard. The Intel docs implicitly acknowledge this and say that the behaviour of this instruction is not specified. Ideally objdump's disassembler would treat this byte sequence as undefined.