From fbbbc243c413ad288088d872fdad6ba84ff7ea3f Mon Sep 17 00:00:00 2001 From: Khairul Azhar Kasmiran Date: Mon, 13 Apr 2020 20:38:01 +0200 Subject: [PATCH] Fix #16433 - Use MOV opcode B8+ for MOV r64, <0x80000000 to 0xffffffff> #16572 ##asm Detailed description I've confirmed #16433 (comment) (including the nasm rax -> eax bug) and thus this pr makes the x86_64 assembler use the MOV B8+ encoding (MOV r64, imm64) when the immediate is between 0x80000000 and 0xffffffff for both: Consistency with GNU assembler. It actually does seem to be the expected encoding. This does mean that mov eax, 0xffffffff and mov rax, 0xffffffff will have very different semantics. --- libr/asm/p/asm_x86_nz.c | 18 +++++++++--------- test/db/asm/x86_64 | 9 ++++++++- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/libr/asm/p/asm_x86_nz.c b/libr/asm/p/asm_x86_nz.c index 2b6a512b76c3f..f2ff5075fcfd0 100644 --- a/libr/asm/p/asm_x86_nz.c +++ b/libr/asm/p/asm_x86_nz.c @@ -1818,14 +1818,13 @@ static int opmov(RAsm *a, ut8 *data, const Opcode *op) { data[l++] = immediate; } else { if (a->bits == 64 && - ((((op->operands[0].type & OT_QWORD) | - (op->operands[1].type & OT_QWORD)) && - immediate < UT32_MAX) || - ((op->operands[0].type & OT_QWORD) && - immediate >= 0xffffffff80000000 /* -0x80000000 */))) { - data[l++] = 0xc7; - data[l++] = 0xc0 | op->operands[0].reg; - imm32in64 = true; + ((!(op->operands[0].type & OT_QWORD) && (op->operands[1].type & OT_QWORD) && + immediate < UT32_MAX) || + ((op->operands[0].type & OT_QWORD) && + (immediate <= ST32_MAX || immediate >= 0xffffffff80000000LL /* -0x80000000 */)))) { + data[l++] = 0xc7; + data[l++] = 0xc0 | op->operands[0].reg; + imm32in64 = true; } else { data[l++] = 0xb8 | op->operands[0].reg; } @@ -1835,7 +1834,8 @@ static int opmov(RAsm *a, ut8 *data, const Opcode *op) { data[l++] = immediate >> 16; data[l++] = immediate >> 24; } - if (a->bits == 64 && immediate > UT32_MAX && !imm32in64) { + if (a->bits == 64 && (immediate > UT32_MAX || (op->operands[0].type & OT_QWORD)) && + !imm32in64) { data[l++] = immediate >> 32; data[l++] = immediate >> 40; data[l++] = immediate >> 48; diff --git a/test/db/asm/x86_64 b/test/db/asm/x86_64 index cd2c7492d5c11..7c0faa9c1e073 100644 --- a/test/db/asm/x86_64 +++ b/test/db/asm/x86_64 @@ -39,6 +39,14 @@ aB "mov rax, 0x112233445566778899" 00 a "mov rax, 3" 48c7c003000000 a "mov rax, 33" 48c7c021000000 ad "mov rax, 0x7fffffff" 48c7c0ffffff7f +a "mov rax, 0x80000000" 48b80000008000000000 +ad "movabs rax, 0x80000000" 48b80000008000000000 +a "mov rax, 0xdeadbeef" 48b8efbeadde00000000 +ad "movabs rax, 0xdeadbeef" 48b8efbeadde00000000 +a "mov rax, 0xffffffff" 48b8ffffffff00000000 +ad "movabs rax, 0xffffffff" 48b8ffffffff00000000 +a "mov rax, 0x100000000" 48b80000000001000000 +ad "movabs rax, 0x100000000" 48b80000000001000000 ad "mov rax, 0" 48c7c000000000 a "mov rax, -1" 48c7c0ffffffff adB "mov rax, 0xffffffffffffffff" 48c7c0ffffffff @@ -740,7 +748,6 @@ aB "mov qword[r12], rsp" 49892424 aB "mov qword[r8 + 0x20], rax" 49894020 aB "mov r12, qword[r12]" 4d8b2424 a "mov eax,r12d" 4489e0 -ad "movabs rax, 0xdeadbeef" 48b8efbeadde00000000 ad "movabs r12, 1" 49bc0100000000000000 a "inc al" fec0 a "inc BYTE PTR [r12]" 41fe0424