/** * @file scc_mcode_amd64.h * @author your name (you@domain.com) * @brief * @version 0.1 * @date 2026-03-13 * * @copyright Copyright (c) 2026 * */ #ifndef __SCC_MCODE_AMD64_H__ #define __SCC_MCODE_AMD64_H__ ///< @warning WRITE BY AI #include // 提供 u8, u32, u64 等 #include // 提供 scc_mcode_t 和写入函数 // ==================== 寄存器编号 ==================== #define SCC_AMD64_RAX 0 #define SCC_AMD64_RCX 1 #define SCC_AMD64_RDX 2 #define SCC_AMD64_RBX 3 #define SCC_AMD64_RSP 4 #define SCC_AMD64_RBP 5 #define SCC_AMD64_RSI 6 #define SCC_AMD64_RDI 7 #define SCC_AMD64_R8 8 #define SCC_AMD64_R9 9 #define SCC_AMD64_R10 10 #define SCC_AMD64_R11 11 #define SCC_AMD64_R12 12 #define SCC_AMD64_R13 13 #define SCC_AMD64_R14 14 #define SCC_AMD64_R15 15 // ==================== 条件码(用于 Jcc 等) ==================== #define SCC_AMD64_COND_O 0 // overflow #define SCC_AMD64_COND_NO 1 // not overflow #define SCC_AMD64_COND_B 2 // below (unsigned) #define SCC_AMD64_COND_AE 3 // above or equal (unsigned) #define SCC_AMD64_COND_E 4 // equal #define SCC_AMD64_COND_NE 5 // not equal #define SCC_AMD64_COND_BE 6 // below or equal (unsigned) #define SCC_AMD64_COND_A 7 // above (unsigned) #define SCC_AMD64_COND_S 8 // sign (negative) #define SCC_AMD64_COND_NS 9 // not sign #define SCC_AMD64_COND_P 10 // parity even #define SCC_AMD64_COND_NP 11 // parity odd #define SCC_AMD64_COND_L 12 // less (signed) #define SCC_AMD64_COND_GE 13 // greater or equal (signed) #define SCC_AMD64_COND_LE 14 // less or equal (signed) #define SCC_AMD64_COND_G 15 // greater (signed) #define SCC_MCODE_FUNC [[maybe_unused]] static inline // ==================== REX 前缀辅助 ==================== /** * @brief 生成 REX 前缀(若不为 0x40 则写入) * * @param mcode 机器码缓冲区 * @param w REX.W 位 * @param r REX.R 位 * @param x REX.X 位 * @param b REX.B 位 */ SCC_MCODE_FUNC void scc_mcode_amd64_rex(scc_mcode_t *mcode, u8 w, u8 r, u8 x, u8 b) { u8 rex = 0x40 | (w << 3) | (r << 2) | (x << 1) | b; if (rex != 0x40) scc_mcode_add_u8(mcode, rex); } // ==================== 内部辅助函数 ==================== /** * @brief 根据目标寄存器和源寄存器生成 REX 位掩码(用于 reg 和 r/m 字段) * * @param dst_reg 目标寄存器编号 * @param src_reg 源寄存器编号 * @param use_w 是否设置 REX.W * @param p_rex 输出 REX 值 * @param p_dst_low 输出 dst 的低 3 位 * @param p_src_low 输出 src 的低 3 位 * @return 是否需要写入 REX 前缀(0 表示不需要) */ SCC_MCODE_FUNC int scc_mcode_amd64_prepare_rex(int dst_reg, int src_reg, int use_w, u8 *p_rex, u8 *p_dst_low, u8 *p_src_low) { u8 rex = 0x40; if (use_w) rex |= 0x08; if (dst_reg >= 8) rex |= 0x01; // REX.B if (src_reg >= 8) rex |= 0x04; // REX.R *p_dst_low = dst_reg & 7; *p_src_low = src_reg & 7; *p_rex = rex; return (rex != 0x40); } /** * @brief 根据操作数宽度添加必要前缀(16 位添加 0x66,32 位无前缀,64 位需配合 * REX.W) * * @param mcode 机器码缓冲区 * @param width 宽度(1=8位,2=16位,4=32位,8=64位) */ SCC_MCODE_FUNC void scc_mcode_amd64_emit_width_prefix(scc_mcode_t *mcode, int width) { if (width == 2) { scc_mcode_add_u8(mcode, 0x66); } // 32 位无前缀,64 位通过 REX.W 处理(由调用者设置) } // ==================== 栈操作 ==================== /** * @brief 压入 64 位寄存器 * * @param mcode 机器码缓冲区 * @param reg 寄存器编号 */ SCC_MCODE_FUNC void scc_mcode_amd64_push_r64(scc_mcode_t *mcode, int reg) { if (reg < 8) { scc_mcode_add_u8(mcode, 0x50 + reg); } else { scc_mcode_amd64_rex(mcode, 0, 0, 0, 1); // REX.B scc_mcode_add_u8(mcode, 0x50 + (reg - 8)); } } /** * @brief 弹出到 64 位寄存器 * * @param mcode 机器码缓冲区 * @param reg 寄存器编号 */ SCC_MCODE_FUNC void scc_mcode_amd64_pop_r64(scc_mcode_t *mcode, int reg) { if (reg < 8) { scc_mcode_add_u8(mcode, 0x58 + reg); } else { scc_mcode_amd64_rex(mcode, 0, 0, 0, 1); // REX.B scc_mcode_add_u8(mcode, 0x58 + (reg - 8)); } } /** * @brief 压入 32 位立即数(符号扩展至 64 位) * * @param mcode 机器码缓冲区 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_push_imm32(scc_mcode_t *mcode, u32 imm) { scc_mcode_add_u8(mcode, 0x68); scc_mcode_add_u32(mcode, imm); } // ==================== 数据传送 ==================== // ---------- 64 位 ---------- /** * @brief 将 64 位立即数移动到 64 位寄存器 (mov r64, imm64) * * @param mcode 机器码缓冲区 * @param reg 目标寄存器 * @param imm 64 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_imm64(scc_mcode_t *mcode, int reg, u64 imm) { u8 rex = 0x48; // REX.W if (reg >= 8) { rex |= 0x01; // REX.B reg -= 8; } scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xB8 + reg); scc_mcode_add_u64(mcode, imm); } /** * @brief 将 32 位立即数移动到 64 位寄存器(高 32 位清零)(mov r64, imm32) * * @param mcode 机器码缓冲区 * @param reg 目标寄存器 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_imm32(scc_mcode_t *mcode, int reg, u32 imm) { u8 rex = 0x40; // REX.W=0 if (reg >= 8) { rex |= 0x01; // REX.B reg -= 8; } scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xB8 + reg); scc_mcode_add_u32(mcode, imm); } /** * @brief 64 位寄存器之间传送 (mov r64, r64) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_r64(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; // REX.W if (src >= 8) rex |= 0x04; // REX.R if (dst >= 8) rex |= 0x01; // REX.B scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x89); // MOV r/m, r u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); scc_mcode_add_u8(mcode, modrm); } /** * @brief 存储 64 位寄存器到 [base] (mov [base], r64) * * @param mcode 机器码缓冲区 * @param base 基址寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_m64_r64(scc_mcode_t *mcode, int base, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x89); u8 modrm = (base & 7) | ((src & 7) << 3); // mod=00 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } /** * @brief 从 [base] 加载到 64 位寄存器 (mov r64, [base]) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param base 基址寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_m64(scc_mcode_t *mcode, int dst, int base) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x8B); u8 modrm = (base & 7) | ((dst & 7) << 3); // mod=00 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } /** * @brief 存储 64 位寄存器到 [base + disp32] (mov [base+disp32], r64) * * @param mcode 机器码缓冲区 * @param base 基址寄存器 * @param disp 32 位偏移 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_m64_disp32_r64(scc_mcode_t *mcode, int base, u32 disp, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x89); u8 modrm = 0x80 | (base & 7) | ((src & 7) << 3); // mod=10 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } scc_mcode_add_u32(mcode, disp); } /** * @brief 从 [base + disp32] 加载到 64 位寄存器 (mov r64, [base+disp32]) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param base 基址寄存器 * @param disp 32 位偏移 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_m64_disp32(scc_mcode_t *mcode, int dst, int base, u32 disp) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x8B); u8 modrm = 0x80 | (base & 7) | ((dst & 7) << 3); // mod=10 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } scc_mcode_add_u32(mcode, disp); } /** * @brief 加载 RIP 相对地址到 64 位寄存器 (lea r64, [rip+disp32]) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 (0-15) * @param disp 32 位相对偏移量 (有符号) */ SCC_MCODE_FUNC void scc_mcode_amd64_lea_r64_rip_rel32(scc_mcode_t *mcode, int dst, u32 disp) { // REX.W = 1, 无额外扩展位(RIP 不是通用寄存器,不涉及 REX.B/R/X) u8 rex = 0x48; if (dst >= 8) { rex |= 0x04; // REX.R 位,因为 dst 放在 reg 字段 dst -= 8; } scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x8D); // LEA opcode // ModRM: mod=00 (无位移), reg=dst, r/m=101 (RIP 相对寻址) u8 modrm = 0x05 | ((dst & 7) << 3); scc_mcode_add_u8(mcode, modrm); // disp32 (有符号) scc_mcode_add_u32(mcode, (u32)disp); } /** * @brief 加载有效地址到 64 位寄存器 (lea r64, [base+disp32]) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param base 基址寄存器 * @param disp 32 位偏移 */ SCC_MCODE_FUNC void scc_mcode_amd64_lea_r64_m64_disp32(scc_mcode_t *mcode, int dst, int base, u32 disp) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x8D); u8 modrm = 0x80 | (base & 7) | ((dst & 7) << 3); // mod=10 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } scc_mcode_add_u32(mcode, disp); } // ---------- 32 位 ---------- /** * @brief 32 位寄存器之间传送 (mov r32, r32) 高 32 位清零 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器(低 32 位) * @param src 源寄存器(低 32 位) */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r32_r32(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x40; // REX.W=0 if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x89); u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); scc_mcode_add_u8(mcode, modrm); } /** * @brief 将 32 位立即数移动到 32 位寄存器(高 32 位清零)(mov r32, imm32) * * @param mcode 机器码缓冲区 * @param reg 目标寄存器 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r32_imm32(scc_mcode_t *mcode, int reg, u32 imm) { scc_mcode_amd64_mov_r64_imm32(mcode, reg, imm); // 与 64 位 imm32 版本相同 } /** * @brief 存储 32 位寄存器到 [base] (mov [base], r32) * * @param mcode 机器码缓冲区 * @param base 基址寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_m32_r32(scc_mcode_t *mcode, int base, int src) { u8 rex = 0x40; // REX.W=0 if (src >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x89); u8 modrm = (base & 7) | ((src & 7) << 3); // mod=00 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } /** * @brief 从 [base] 加载到 32 位寄存器 (mov r32, [base]) 高 32 位清零 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param base 基址寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r32_m32(scc_mcode_t *mcode, int dst, int base) { u8 rex = 0x40; // REX.W=0 if (dst >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x8B); u8 modrm = (base & 7) | ((dst & 7) << 3); // mod=00 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } // ---------- 16 位 ---------- /** * @brief 16 位寄存器之间传送 (mov r16, r16) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器(低 16 位) * @param src 源寄存器(低 16 位) */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r16_r16(scc_mcode_t *mcode, int dst, int src) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; // REX.W=0 if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x89); u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); scc_mcode_add_u8(mcode, modrm); } /** * @brief 将 16 位立即数移动到 16 位寄存器 (mov r16, imm16) * * @param mcode 机器码缓冲区 * @param reg 目标寄存器 * @param imm 16 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r16_imm16(scc_mcode_t *mcode, int reg, u16 imm) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; // REX.W=0 if (reg >= 8) { rex |= 0x01; reg -= 8; } scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xB8 + reg); scc_mcode_add_u16(mcode, imm); } /** * @brief 存储 16 位寄存器到 [base] (mov [base], r16) * * @param mcode 机器码缓冲区 * @param base 基址寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_m16_r16(scc_mcode_t *mcode, int base, int src) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; if (src >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x89); u8 modrm = (base & 7) | ((src & 7) << 3); // mod=00 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } /** * @brief 从 [base] 加载到 16 位寄存器 (mov r16, [base]) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param base 基址寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r16_m16(scc_mcode_t *mcode, int dst, int base) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; if (dst >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x8B); u8 modrm = (base & 7) | ((dst & 7) << 3); // mod=00 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } // ---------- 8 位 ---------- /** * @brief 检查 8 位寄存器是否需要 REX 前缀 * * 若寄存器编号为 4-7(SPL、BPL、SIL、DIL),必须使用 REX 前缀 * * @param reg 寄存器编号 * @return 是否需要 REX 前缀 */ SCC_MCODE_FUNC int scc_mcode_amd64_is_byte_reg_needs_rex(int reg) { return (reg >= 4 && reg <= 7) || reg >= 8; } /** * @brief 8 位寄存器之间传送 (mov r8, r8) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器(低 8 位) * @param src 源寄存器(低 8 位) */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r8_r8(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst) || scc_mcode_amd64_is_byte_reg_needs_rex(src); if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0x88); // MOV r/m8, r8 u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); scc_mcode_add_u8(mcode, modrm); } /** * @brief 将 8 位立即数移动到 8 位寄存器 (mov r8, imm8) * * @param mcode 机器码缓冲区 * @param reg 目标寄存器 * @param imm 8 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r8_imm8(scc_mcode_t *mcode, int reg, u8 imm) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(reg); if (reg >= 8) { rex |= 0x01; reg -= 8; } if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0xB0 + reg); scc_mcode_add_u8(mcode, imm); } /** * @brief 存储 8 位寄存器到 [base] (mov [base], r8) * * @param mcode 机器码缓冲区 * @param base 基址寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_m8_r8(scc_mcode_t *mcode, int base, int src) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(src) || scc_mcode_amd64_is_byte_reg_needs_rex(base); if (src >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0x88); u8 modrm = (base & 7) | ((src & 7) << 3); // mod=00 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } /** * @brief 从 [base] 加载到 8 位寄存器 (mov r8, [base]) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param base 基址寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r8_m8(scc_mcode_t *mcode, int dst, int base) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst) || scc_mcode_amd64_is_byte_reg_needs_rex(base); if (dst >= 8) rex |= 0x04; if (base >= 8) rex |= 0x01; if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0x8A); u8 modrm = (base & 7) | ((dst & 7) << 3); // mod=00 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } // ---------- 符号/零扩展传送 ---------- /** * @brief 符号扩展传送 (movsx r64, r/m8) * * @param mcode 机器码缓冲区 * @param dst 64 位目标寄存器 * @param src 8 位源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_r8(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; // REX.W if (dst >= 8) rex |= 0x04; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x0F); scc_mcode_add_u8(mcode, 0xBE); u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); scc_mcode_add_u8(mcode, modrm); } /** * @brief 符号扩展传送 (movsx r64, r/m16) * * @param mcode 机器码缓冲区 * @param dst 64 位目标寄存器 * @param src 16 位源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_r16(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x0F); scc_mcode_add_u8(mcode, 0xBF); u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); scc_mcode_add_u8(mcode, modrm); } /** * @brief 符号扩展传送 (movsx r64, r/m32) * * @param mcode 机器码缓冲区 * @param dst 64 位目标寄存器 * @param src 32 位源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_r32(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x63); u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); scc_mcode_add_u8(mcode, modrm); } /** * @brief 零扩展传送 (movzx r64, r/m8) * * @param mcode 机器码缓冲区 * @param dst 64 位目标寄存器 * @param src 8 位源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_r8(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x0F); scc_mcode_add_u8(mcode, 0xB6); u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); scc_mcode_add_u8(mcode, modrm); } /** * @brief 零扩展传送 (movzx r64, r/m16) * * @param mcode 机器码缓冲区 * @param dst 64 位目标寄存器 * @param src 16 位源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_r16(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x0F); scc_mcode_add_u8(mcode, 0xB7); u8 modrm = 0xC0 | ((src & 7) << 3) | (dst & 7); scc_mcode_add_u8(mcode, modrm); } // ==================== 算术运算 ==================== // ---------- 64 位 ---------- /** * @brief 64 位加法 ADD r64, r64 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_add_r64_r64(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x01); // ADD r/m, r u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 64 位加法 ADD r64, imm32 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_add_r64_imm32(scc_mcode_t *mcode, int dst, u32 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x81); u8 modrm = 0xC0 | (dst & 7) | (0 << 3); // reg/opcode = 0 for ADD scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u32(mcode, imm); } /** * @brief 64 位减法 SUB r64, r64 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_sub_r64_r64(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x29); // SUB r/m, r u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 64 位减法 SUB r64, imm32 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_sub_r64_imm32(scc_mcode_t *mcode, int dst, u32 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x81); u8 modrm = 0xC0 | (dst & 7) | (5 << 3); // reg/opcode = 5 for SUB scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u32(mcode, imm); } /** * @brief 调整 RSP 专用减法 (sub rsp, imm32) * * @param mcode 机器码缓冲区 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_sub_rsp_imm32(scc_mcode_t *mcode, u32 imm) { scc_mcode_amd64_sub_r64_imm32(mcode, SCC_AMD64_RSP, imm); } /** * @brief 调整 RSP 专用加法 (add rsp, imm32) * * @param mcode 机器码缓冲区 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_add_rsp_imm32(scc_mcode_t *mcode, u32 imm) { scc_mcode_amd64_add_r64_imm32(mcode, SCC_AMD64_RSP, imm); } /** * @brief 64 位比较 CMP r64, r64 * * @param mcode 机器码缓冲区 * @param dst 左操作数寄存器 * @param src 右操作数寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_cmp_r64_r64(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x39); // CMP r/m, r u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 64 位比较 CMP r64, imm32 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_cmp_r64_imm32(scc_mcode_t *mcode, int dst, u32 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x81); u8 modrm = 0xC0 | (dst & 7) | (7 << 3); // reg/opcode = 7 for CMP scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u32(mcode, imm); } /** * @brief 两操作数有符号乘法 IMUL r64, r64 (r64 = r64 * r64) * * @param mcode 机器码缓冲区 * @param dst 目标/左操作数寄存器 * @param src 右操作数寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_imul_r64_r64(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; // dst in reg field if (src >= 8) rex |= 0x01; // src in r/m field scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x0F); scc_mcode_add_u8(mcode, 0xAF); u8 modrm = 0xC0 | (src & 7) | ((dst & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 三操作数有符号乘法 IMUL r64, r/m64, imm32 (r64 = r/m64 * imm32) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器或内存(此处为寄存器版本) * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_imul_r64_r64_imm32(scc_mcode_t *mcode, int dst, int src, u32 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x69); u8 modrm = 0xC0 | (src & 7) | ((dst & 7) << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u32(mcode, imm); } /** * @brief 三操作数有符号乘法 IMUL r64, r/m64, imm8 (符号扩展) (r64 = r/m64 * * imm8) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器或内存(此处为寄存器版本) * @param imm 8 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_imul_r64_r64_imm8(scc_mcode_t *mcode, int dst, int src, u8 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x6B); u8 modrm = 0xC0 | (src & 7) | ((dst & 7) << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, imm); } // ---------- 32 位 ---------- /** * @brief 32 位加法 ADD r32, r32 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_add_r32_r32(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x40; // REX.W=0 if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x01); u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 32 位加法 ADD r32, imm32 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_add_r32_imm32(scc_mcode_t *mcode, int dst, u32 imm) { u8 rex = 0x40; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x81); u8 modrm = 0xC0 | (dst & 7) | (0 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u32(mcode, imm); } /** * @brief 32 位减法 SUB r32, r32 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_sub_r32_r32(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x40; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x29); u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 32 位比较 CMP r32, r32 * * @param mcode 机器码缓冲区 * @param dst 左操作数寄存器 * @param src 右操作数寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_cmp_r32_r32(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x40; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x39); u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } // ---------- 16 位 ---------- /** * @brief 16 位加法 ADD r16, r16 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_add_r16_r16(scc_mcode_t *mcode, int dst, int src) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x01); u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 16 位加法 ADD r16, imm16 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 16 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_add_r16_imm16(scc_mcode_t *mcode, int dst, u16 imm) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x81); u8 modrm = 0xC0 | (dst & 7) | (0 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u16(mcode, imm); } /** * @brief 16 位减法 SUB r16, r16 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_sub_r16_r16(scc_mcode_t *mcode, int dst, int src) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x29); u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 16 位比较 CMP r16, r16 * * @param mcode 机器码缓冲区 * @param dst 左操作数寄存器 * @param src 右操作数寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_cmp_r16_r16(scc_mcode_t *mcode, int dst, int src) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x39); u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } // ---------- 8 位 ---------- /** * @brief 8 位加法 ADD r8, r8 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_add_r8_r8(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst) || scc_mcode_amd64_is_byte_reg_needs_rex(src); if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0x00); // ADD r/m8, r8 u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 8 位加法 ADD r8, imm8 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 8 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_add_r8_imm8(scc_mcode_t *mcode, int dst, u8 imm) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst); if (dst >= 8) { rex |= 0x01; dst -= 8; } if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0x80); // ADD r/m8, imm8 u8 modrm = 0xC0 | (dst & 7) | (0 << 3); // reg/opcode = 0 for ADD scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, imm); } /** * @brief 8 位减法 SUB r8, r8 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_sub_r8_r8(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst) || scc_mcode_amd64_is_byte_reg_needs_rex(src); if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0x28); // SUB r/m8, r8 u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 8 位比较 CMP r8, r8 * * @param mcode 机器码缓冲区 * @param dst 左操作数寄存器 * @param src 右操作数寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_cmp_r8_r8(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst) || scc_mcode_amd64_is_byte_reg_needs_rex(src); if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0x38); // CMP r/m8, r8 u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } // ==================== 单操作数乘除 ==================== // ---------- 无符号乘法 MUL ---------- /** * @brief 无符号乘法 MUL r/m64 (RDX:RAX = RAX * r/m64) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mul_r64(scc_mcode_t *mcode, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (4 << 3); // reg/opcode = 4 for MUL scc_mcode_add_u8(mcode, modrm); } /** * @brief 无符号乘法 MUL r/m32 (EDX:EAX = EAX * r/m32) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mul_r32(scc_mcode_t *mcode, int src) { u8 rex = 0x40; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 无符号乘法 MUL r/m16 (DX:AX = AX * r/m16) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mul_r16(scc_mcode_t *mcode, int src) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 无符号乘法 MUL r/m8 (AX = AL * r/m8) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mul_r8(scc_mcode_t *mcode, int src) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(src); if (src >= 8) rex |= 0x01; if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0xF6); u8 modrm = 0xC0 | (src & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); } // ---------- 有符号乘法 IMUL (单操作数) ---------- /** * @brief 有符号乘法 IMUL r/m64 (RDX:RAX = RAX * r/m64) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_imul_r64_1op(scc_mcode_t *mcode, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (5 << 3); // reg/opcode = 5 for IMUL scc_mcode_add_u8(mcode, modrm); } /** * @brief 有符号乘法 IMUL r/m32 (EDX:EAX = EAX * r/m32) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_imul_r32_1op(scc_mcode_t *mcode, int src) { u8 rex = 0x40; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (5 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 有符号乘法 IMUL r/m16 (DX:AX = AX * r/m16) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_imul_r16_1op(scc_mcode_t *mcode, int src) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (5 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 有符号乘法 IMUL r/m8 (AX = AL * r/m8) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_imul_r8_1op(scc_mcode_t *mcode, int src) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(src); if (src >= 8) rex |= 0x01; if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0xF6); u8 modrm = 0xC0 | (src & 7) | (5 << 3); scc_mcode_add_u8(mcode, modrm); } // ---------- 无符号除法 DIV ---------- /** * @brief 无符号除法 DIV r/m64 (RDX:RAX / r/m64, 商 RAX, 余 RDX) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_div_r64(scc_mcode_t *mcode, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (6 << 3); // reg/opcode = 6 for DIV scc_mcode_add_u8(mcode, modrm); } /** * @brief 无符号除法 DIV r/m32 (EDX:EAX / r/m32, 商 EAX, 余 EDX) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_div_r32(scc_mcode_t *mcode, int src) { u8 rex = 0x40; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (6 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 无符号除法 DIV r/m16 (DX:AX / r/m16, 商 AX, 余 DX) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_div_r16(scc_mcode_t *mcode, int src) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (6 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 无符号除法 DIV r/m8 (AX / r/m8, 商 AL, 余 AH) * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_div_r8(scc_mcode_t *mcode, int src) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(src); if (src >= 8) rex |= 0x01; if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0xF6); u8 modrm = 0xC0 | (src & 7) | (6 << 3); scc_mcode_add_u8(mcode, modrm); } // ---------- 有符号除法 IDIV ---------- /** * @brief 有符号除法 IDIV r/m64 * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_idiv_r64(scc_mcode_t *mcode, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (7 << 3); // reg/opcode = 7 for IDIV scc_mcode_add_u8(mcode, modrm); } /** * @brief 有符号除法 IDIV r/m32 * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_idiv_r32(scc_mcode_t *mcode, int src) { u8 rex = 0x40; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (7 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 有符号除法 IDIV r/m16 * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_idiv_r16(scc_mcode_t *mcode, int src) { scc_mcode_amd64_emit_width_prefix(mcode, 2); u8 rex = 0x40; if (src >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xF7); u8 modrm = 0xC0 | (src & 7) | (7 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 有符号除法 IDIV r/m8 * * @param mcode 机器码缓冲区 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_idiv_r8(scc_mcode_t *mcode, int src) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(src); if (src >= 8) rex |= 0x01; if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0xF6); u8 modrm = 0xC0 | (src & 7) | (7 << 3); scc_mcode_add_u8(mcode, modrm); } // ==================== 按位逻辑 ==================== // 仅提供 64 位和 32 位示例,其他宽度可仿照上述模式自行扩展 /** * @brief 64 位与 AND r64, r64 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_and_r64_r64(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x21); u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 64 位与 AND r64, imm32 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_and_r64_imm32(scc_mcode_t *mcode, int dst, u32 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x81); u8 modrm = 0xC0 | (dst & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u32(mcode, imm); } /** * @brief 64 位或 OR r64, r64 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_or_r64_r64(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x09); u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 64 位或 OR r64, imm32 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_or_r64_imm32(scc_mcode_t *mcode, int dst, u32 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x81); u8 modrm = 0xC0 | (dst & 7) | (1 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u32(mcode, imm); } /** * @brief 64 位异或 XOR r64, r64 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_xor_r64_r64(scc_mcode_t *mcode, int dst, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x04; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x31); u8 modrm = 0xC0 | (dst & 7) | ((src & 7) << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 64 位异或 XOR r64, imm32 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 32 位立即数 */ SCC_MCODE_FUNC void scc_mcode_amd64_xor_r64_imm32(scc_mcode_t *mcode, int dst, u32 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x81); u8 modrm = 0xC0 | (dst & 7) | (6 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u32(mcode, imm); } // ==================== 移位 ==================== // 提供 64 位示例,其他宽度可类似添加 /** * @brief 64 位左移 SHL r64, 1 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_shl_r64_1(scc_mcode_t *mcode, int dst) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xD1); u8 modrm = 0xC0 | (dst & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 64 位左移 SHL r64, imm8 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 移位次数 */ SCC_MCODE_FUNC void scc_mcode_amd64_shl_r64_imm8(scc_mcode_t *mcode, int dst, u8 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xC1); u8 modrm = 0xC0 | (dst & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, imm); } /** * @brief 64 位右移 SHR r64, 1 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_shr_r64_1(scc_mcode_t *mcode, int dst) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xD1); u8 modrm = 0xC0 | (dst & 7) | (5 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 64 位右移 SHR r64, imm8 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 移位次数 */ SCC_MCODE_FUNC void scc_mcode_amd64_shr_r64_imm8(scc_mcode_t *mcode, int dst, u8 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xC1); u8 modrm = 0xC0 | (dst & 7) | (5 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, imm); } /** * @brief 64 位算术右移 SAR r64, 1 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_sar_r64_1(scc_mcode_t *mcode, int dst) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xD1); u8 modrm = 0xC0 | (dst & 7) | (7 << 3); scc_mcode_add_u8(mcode, modrm); } /** * @brief 64 位算术右移 SAR r64, imm8 * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param imm 移位次数 */ SCC_MCODE_FUNC void scc_mcode_amd64_sar_r64_imm8(scc_mcode_t *mcode, int dst, u8 imm) { u8 rex = 0x48; if (dst >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xC1); u8 modrm = 0xC0 | (dst & 7) | (7 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, imm); } // ==================== 条件设置 ==================== /** * @brief 根据条件码设置字节寄存器 (setcc r8) * * @param mcode 机器码缓冲区 * @param cond 条件码(0-15) * @param reg 目标 8 位寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_setcc_r8(scc_mcode_t *mcode, int cond, int reg) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(reg); if (reg >= 8) { rex |= 0x01; reg -= 8; } if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0x0F); scc_mcode_add_u8(mcode, 0x90 + cond); u8 modrm = 0xC0 | (reg & 7); // reg/opcode 字段未使用 scc_mcode_add_u8(mcode, modrm); } /** * @brief 根据条件码设置内存字节 (setcc [base]) * * @param mcode 机器码缓冲区 * @param cond 条件码 * @param base 基址寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_setcc_m8(scc_mcode_t *mcode, int cond, int base) { u8 rex = 0x40; int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(base); if (base >= 8) { rex |= 0x01; base -= 8; } if (need_rex) { scc_mcode_add_u8(mcode, rex); } scc_mcode_add_u8(mcode, 0x0F); scc_mcode_add_u8(mcode, 0x90 + cond); u8 modrm = 0x00 | (base & 7); // mod=00, reg 字段未使用(置0) if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } // ==================== 控制转移 ==================== /** * @brief 相对跳转 JMP rel32 * * @param mcode 机器码缓冲区 * @param rel32 32 位相对偏移 */ SCC_MCODE_FUNC void scc_mcode_amd64_jmp_rel32(scc_mcode_t *mcode, u32 rel32) { scc_mcode_add_u8(mcode, 0xE9); scc_mcode_add_u32(mcode, rel32); } /** * @brief 条件跳转 Jcc rel32 * * @param mcode 机器码缓冲区 * @param cond 条件码 * @param rel32 32 位相对偏移 */ SCC_MCODE_FUNC void scc_mcode_amd64_jcc_rel32(scc_mcode_t *mcode, int cond, u32 rel32) { scc_mcode_add_u8(mcode, 0x0F); scc_mcode_add_u8(mcode, 0x80 + cond); scc_mcode_add_u32(mcode, rel32); } /** * @brief 相对调用 CALL rel32 * * @param mcode 机器码缓冲区 * @param rel32 32 位相对偏移 */ SCC_MCODE_FUNC void scc_mcode_amd64_call_rel32(scc_mcode_t *mcode, u32 rel32) { scc_mcode_add_u8(mcode, 0xE8); scc_mcode_add_u32(mcode, rel32); } /** * @brief 间接跳转 JMP r64 * * @param mcode 机器码缓冲区 * @param reg 目标寄存器(存储跳转地址) */ SCC_MCODE_FUNC void scc_mcode_amd64_jmp_r64(scc_mcode_t *mcode, int reg) { u8 rex = 0x40; if (reg >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xFF); u8 modrm = 0xC0 | (reg & 7) | (4 << 3); // reg/opcode = 4 for JMP r/m64 scc_mcode_add_u8(mcode, modrm); } /** * @brief 间接跳转 JMP [base] (简单基址) * * @param mcode 机器码缓冲区 * @param base 基址寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_jmp_m64(scc_mcode_t *mcode, int base) { u8 rex = 0x48; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xFF); u8 modrm = (base & 7) | (4 << 3); // mod=00, reg/opcode=4 if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } /** * @brief 间接调用 CALL r64 * * @param mcode 机器码缓冲区 * @param reg 目标寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_call_r64(scc_mcode_t *mcode, int reg) { u8 rex = 0x40; if (reg >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xFF); u8 modrm = 0xC0 | (reg & 7) | (2 << 3); // reg/opcode = 2 for CALL r/m64 scc_mcode_add_u8(mcode, modrm); } /** * @brief 间接调用 CALL [base] * * @param mcode 机器码缓冲区 * @param base 基址寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_call_m64(scc_mcode_t *mcode, int base) { u8 rex = 0x48; if (base >= 8) rex |= 0x01; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0xFF); u8 modrm = (base & 7) | (2 << 3); if ((base & 7) == 4) { u8 sib = (base & 7) | (4 << 3); scc_mcode_add_u8(mcode, modrm); scc_mcode_add_u8(mcode, sib); } else { scc_mcode_add_u8(mcode, modrm); } } /** * @brief 返回指令 RET * * @param mcode 机器码缓冲区 */ SCC_MCODE_FUNC void scc_mcode_amd64_ret(scc_mcode_t *mcode) { scc_mcode_add_u8(mcode, 0xC3); } // ==================== 系统调用 ==================== /** * @brief 执行系统调用 SYSCALL * * @param mcode 机器码缓冲区 */ SCC_MCODE_FUNC void scc_mcode_amd64_syscall(scc_mcode_t *mcode) { scc_mcode_add_u8(mcode, 0x0F); scc_mcode_add_u8(mcode, 0x05); } // ==================== 复杂寻址模式(SIB) ==================== // 辅助函数:根据 base, index, scale, disp 生成 ModRM 和 SIB 字节并写入 // 返回需要写入 disp 的字节数(0,1,4),调用者需写入 disp SCC_MCODE_FUNC int scc_mcode_amd64_emit_sib_address(scc_mcode_t *mcode, int base, int index, int scale, u32 disp, int has_disp, int disp8) { // scale 编码: 0=1, 1=2, 2=4, 3=8 u8 scale_code = 0; switch (scale) { case 1: scale_code = 0; break; case 2: scale_code = 1; break; case 4: scale_code = 2; break; case 8: scale_code = 3; break; default: break; // 非法,但默认 0 } u8 index_reg = (index == -1) ? 4 : (index & 7); // 4 表示无 index u8 base_reg = (base == -1) ? 5 : (base & 7); u8 mod = 0; int disp_size = 0; if (base == -1) { // 无基址,只有 index*scale + disp32 mod = 0; base_reg = 5; // 必须为 101 disp_size = 4; } else { if (!has_disp) { mod = 0; disp_size = 0; } else if (disp8 && (disp <= 127 || (int)disp >= -128)) { mod = 1; disp_size = 1; } else { mod = 2; disp_size = 4; } } u8 modrm = (mod << 6) | (0 << 3) | 4; // reg 字段为 0(调用者会覆盖) scc_mcode_add_u8(mcode, modrm); u8 sib = (scale_code << 6) | (index_reg << 3) | base_reg; scc_mcode_add_u8(mcode, sib); return disp_size; } // 示例:带 SIB 的 MOV r64, [base+index*scale+disp32] // /** // * @brief 从复杂地址加载到 64 位寄存器 (mov r64, [base + index*scale + disp]) // * // * @param mcode 机器码缓冲区 // * @param dst 目标寄存器 // * @param base 基址寄存器(-1 表示无基址) // * @param index 索引寄存器(-1 表示无索引) // * @param scale 比例因子(1,2,4,8) // * @param disp 位移量 // * @param disp_size 位移大小(0=无位移,1=8位,4=32位) // */ // SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_m64_sib(scc_mcode_t *mcode, int // dst, // int base, int index, int // scale, u32 disp, int // disp_size) { // u8 rex = 0x48; // if (dst >= 8) // rex |= 0x04; // if (base >= 8 && base != -1) // rex |= 0x01; // if (index >= 8 && index != -1) // rex |= 0x02; // REX.X // scc_mcode_add_u8(mcode, rex); // scc_mcode_add_u8(mcode, 0x8B); // // 保存 ModRM 的 reg 字段为 dst // u8 modrm_byte = (dst & 7) << 3; // // 临时占位,实际 mod 和 rm 由 sib 函数决定 // // 我们先写入一个占位,稍后修改?为了方便,我们重写逻辑:直接调用 sib // // 函数后,在适当位置写入 reg 字段? 更简单:构建 modrm 时,reg // // 已知,我们可以在 sib 函数中传入 reg 参数。 重新设计:让 sib 函数返回 // // modrm 和 sib 的字节,然后我们组合。 // } // 为了简化,我们直接实现一个完整版本,不拆分辅助函数: /** * @brief 从复杂地址加载到 64 位寄存器 (mov r64, [base + index*scale + disp]) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param base 基址寄存器(-1 表示无基址) * @param index 索引寄存器(-1 表示无索引) * @param scale 比例因子(1,2,4,8) * @param disp 位移量 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_r64_m64_sib(scc_mcode_t *mcode, int dst, int base, int index, int scale, u32 disp) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (base >= 8 && base != -1) rex |= 0x01; if (index >= 8 && index != -1) rex |= 0x02; // REX.X scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x8B); int has_disp = (base != -1) ? 1 : 0; // 无基址时必须带 disp32 int disp8 = 0; // 不自动选择,统一用 disp32 简化 int disp_size = 4; if (base != -1) { if (disp == 0) { has_disp = 0; disp_size = 0; } else { // 可添加 disp8 优化,但此处统一 disp32 disp_size = 4; } } u8 scale_code = 0; switch (scale) { case 1: scale_code = 0; break; case 2: scale_code = 1; break; case 4: scale_code = 2; break; case 8: scale_code = 3; break; default: scale_code = 0; break; } u8 index_reg = (index == -1) ? 4 : (index & 7); u8 base_reg = (base == -1) ? 5 : (base & 7); u8 mod = 0; if (base == -1) { mod = 0; base_reg = 5; disp_size = 4; } else { if (!has_disp) { mod = 0; } else { mod = 2; // 强制 disp32 } } u8 modrm = (mod << 6) | ((dst & 7) << 3) | 4; // rm=4 表示使用 SIB scc_mcode_add_u8(mcode, modrm); u8 sib = (scale_code << 6) | (index_reg << 3) | base_reg; scc_mcode_add_u8(mcode, sib); if (disp_size == 4) { scc_mcode_add_u32(mcode, disp); } else if (disp_size == 1) { scc_mcode_add_u8(mcode, (u8)disp); } // 无位移则不添加 } /** * @brief 存储 64 位寄存器到复杂地址 (mov [base+index*scale+disp], r64) * * @param mcode 机器码缓冲区 * @param base 基址寄存器(-1 表示无基址) * @param index 索引寄存器(-1 表示无索引) * @param scale 比例因子 * @param disp 位移量 * @param src 源寄存器 */ SCC_MCODE_FUNC void scc_mcode_amd64_mov_m64_sib_r64(scc_mcode_t *mcode, int base, int index, int scale, u32 disp, int src) { u8 rex = 0x48; if (src >= 8) rex |= 0x04; if (base >= 8 && base != -1) rex |= 0x01; if (index >= 8 && index != -1) rex |= 0x02; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x89); int has_disp = (base != -1) ? 1 : 0; int disp_size = 4; if (base != -1) { if (disp == 0) { has_disp = 0; disp_size = 0; } else { disp_size = 4; } } u8 scale_code = 0; switch (scale) { case 1: scale_code = 0; break; case 2: scale_code = 1; break; case 4: scale_code = 2; break; case 8: scale_code = 3; break; default: scale_code = 0; break; } u8 index_reg = (index == -1) ? 4 : (index & 7); u8 base_reg = (base == -1) ? 5 : (base & 7); u8 mod = 0; if (base == -1) { mod = 0; base_reg = 5; disp_size = 4; } else { if (!has_disp) { mod = 0; } else { mod = 2; } } u8 modrm = (mod << 6) | ((src & 7) << 3) | 4; scc_mcode_add_u8(mcode, modrm); u8 sib = (scale_code << 6) | (index_reg << 3) | base_reg; scc_mcode_add_u8(mcode, sib); if (disp_size == 4) { scc_mcode_add_u32(mcode, disp); } else if (disp_size == 1) { scc_mcode_add_u8(mcode, (u8)disp); } } /** * @brief 加载有效地址到 64 位寄存器 (lea r64, [base+index*scale+disp]) * * @param mcode 机器码缓冲区 * @param dst 目标寄存器 * @param base 基址寄存器(-1 允许) * @param index 索引寄存器(-1 允许) * @param scale 比例因子 * @param disp 位移量 */ SCC_MCODE_FUNC void scc_mcode_amd64_lea_r64_m64_sib(scc_mcode_t *mcode, int dst, int base, int index, int scale, u32 disp) { u8 rex = 0x48; if (dst >= 8) rex |= 0x04; if (base >= 8 && base != -1) rex |= 0x01; if (index >= 8 && index != -1) rex |= 0x02; scc_mcode_add_u8(mcode, rex); scc_mcode_add_u8(mcode, 0x8D); int has_disp = (base != -1) ? 1 : 0; int disp_size = 4; if (base != -1) { if (disp == 0) { has_disp = 0; disp_size = 0; } else { disp_size = 4; } } u8 scale_code = 0; switch (scale) { case 1: scale_code = 0; break; case 2: scale_code = 1; break; case 4: scale_code = 2; break; case 8: scale_code = 3; break; default: scale_code = 0; break; } u8 index_reg = (index == -1) ? 4 : (index & 7); u8 base_reg = (base == -1) ? 5 : (base & 7); u8 mod = 0; if (base == -1) { mod = 0; base_reg = 5; disp_size = 4; } else { if (!has_disp) { mod = 0; } else { mod = 2; } } u8 modrm = (mod << 6) | ((dst & 7) << 3) | 4; scc_mcode_add_u8(mcode, modrm); u8 sib = (scale_code << 6) | (index_reg << 3) | base_reg; scc_mcode_add_u8(mcode, sib); if (disp_size == 4) { scc_mcode_add_u32(mcode, disp); } else if (disp_size == 1) { scc_mcode_add_u8(mcode, (u8)disp); } } #endif /* __SCC_MCODE_AMD64_H__ */