Files
scc/libs/mcode/include/amd64/scc_amd64.h
zzy 4144f7841c refactor(argparse): 将null替换为nullptr以提高C++兼容性
- 在argparse库中将所有null指针常量替换为nullptr
- 更新头文件和源文件中的指针初始化和比较操作
- 修改测试文件中的相关断言检查
- 更新AST定义文件中的注释说明
2026-04-05 20:18:09 +08:00

2532 lines
70 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @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 <scc_core_type.h> // 提供 u8, u32, u64 等
#include <scc_mcode.h> // 提供 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 位添加 0x6632 位无前缀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-7SPL、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);
}
// ==================== 符号/零扩展加载(内存操作数) ====================
/**
* @brief 从内存加载字节并符号扩展到 64 位 (movsx r64, byte ptr [base])
*
* @param mcode 机器码缓冲区
* @param dst 目标 64 位寄存器
* @param base 基址寄存器(存储地址)
*/
SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_m8(scc_mcode_t *mcode, int dst,
int base) {
u8 rex = 0x48; // REX.W = 1
if (dst >= 8)
rex |= 0x04; // REX.R
if (base >= 8)
rex |= 0x01; // REX.B
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0x0F);
scc_mcode_add_u8(mcode, 0xBE); // MOVSX r64, r/m8
u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7);
if ((base & 7) == 4) {
// 需要 SIB 字节 (base == RSP 或 R12)
scc_mcode_add_u8(mcode, modrm);
scc_mcode_add_u8(mcode, 0x24); // SIB: [base] 无索引base=4
} else {
scc_mcode_add_u8(mcode, modrm);
}
}
/**
* @brief 从内存加载字节并零扩展到 64 位 (movzx r64, byte ptr [base])
*
* @param mcode 机器码缓冲区
* @param dst 目标 64 位寄存器
* @param base 基址寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_m8(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, 0x0F);
scc_mcode_add_u8(mcode, 0xB6); // MOVZX r64, r/m8
u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7);
if ((base & 7) == 4) {
scc_mcode_add_u8(mcode, modrm);
scc_mcode_add_u8(mcode, 0x24);
} else {
scc_mcode_add_u8(mcode, modrm);
}
}
/**
* @brief 从内存加载16位并符号扩展到 64 位 (movsx r64, word ptr [base])
*
* @param mcode 机器码缓冲区
* @param dst 目标 64 位寄存器
* @param base 基址寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_m16(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, 0x0F);
scc_mcode_add_u8(mcode, 0xBF); // MOVSX r64, r/m16
u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7);
if ((base & 7) == 4) {
scc_mcode_add_u8(mcode, modrm);
scc_mcode_add_u8(mcode, 0x24);
} else {
scc_mcode_add_u8(mcode, modrm);
}
}
/**
* @brief 从内存加载16位并零扩展到 64 位 (movzx r64, word ptr [base])
*
* @param mcode 机器码缓冲区
* @param dst 目标 64 位寄存器
* @param base 基址寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_movzx_r64_m16(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, 0x0F);
scc_mcode_add_u8(mcode, 0xB7); // MOVZX r64, r/m16
u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7);
if ((base & 7) == 4) {
scc_mcode_add_u8(mcode, modrm);
scc_mcode_add_u8(mcode, 0x24);
} else {
scc_mcode_add_u8(mcode, modrm);
}
}
/**
* @brief 从内存加载32位并符号扩展到 64 位 (movsxd r64, dword ptr [base])
*
* @param mcode 机器码缓冲区
* @param dst 目标 64 位寄存器
* @param base 基址寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_movsx_r64_m32(scc_mcode_t *mcode, int dst,
int base) {
u8 rex = 0x48; // REX.W = 1, 对应 MOVSXD
if (dst >= 8)
rex |= 0x04;
if (base >= 8)
rex |= 0x01;
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0x63); // MOVSXD r64, r/m32
u8 modrm = 0x00 | ((dst & 7) << 3) | (base & 7);
if ((base & 7) == 4) {
scc_mcode_add_u8(mcode, modrm);
scc_mcode_add_u8(mcode, 0x24);
} else {
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);
}
/**
* @brief 64 位按位取反 NOT r64
*
* @param mcode 机器码缓冲区
* @param dst 目标寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_not_r64(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, 0xF7);
u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT
scc_mcode_add_u8(mcode, modrm);
}
/**
* @brief 32 位按位取反 NOT r32
*
* @param mcode 机器码缓冲区
* @param dst 目标寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_not_r32(scc_mcode_t *mcode, int dst) {
u8 rex = 0x40; // REX.W=0
if (dst >= 8)
rex |= 0x01;
scc_mcode_add_u8(mcode, rex);
scc_mcode_add_u8(mcode, 0xF7);
u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT
scc_mcode_add_u8(mcode, modrm);
}
/**
* @brief 16 位按位取反 NOT r16
*
* @param mcode 机器码缓冲区
* @param dst 目标寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_not_r16(scc_mcode_t *mcode, int dst) {
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, 0xF7);
u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT
scc_mcode_add_u8(mcode, modrm);
}
/**
* @brief 8 位按位取反 NOT r8
*
* @param mcode 机器码缓冲区
* @param dst 目标寄存器
*/
SCC_MCODE_FUNC void scc_mcode_amd64_not_r8(scc_mcode_t *mcode, int dst) {
u8 rex = 0x40;
int need_rex = scc_mcode_amd64_is_byte_reg_needs_rex(dst);
if (dst >= 8)
rex |= 0x01;
if (need_rex) {
scc_mcode_add_u8(mcode, rex);
}
scc_mcode_add_u8(mcode, 0xF6); // 8位版本使用0xF6
u8 modrm = 0xC0 | (dst & 7) | (2 << 3); // reg/opcode = 2 for NOT
scc_mcode_add_u8(mcode, modrm);
}
// ==================== 移位 ====================
// 提供 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 通过内存地址调用 (call [rip+disp32]) - 通常用于导入表调用
*
* @param mcode 机器码缓冲区
* @param disp 32 位相对偏移
*/
SCC_MCODE_FUNC void scc_mcode_amd64_call_mem_rip_rel32(scc_mcode_t *mcode,
u32 disp) {
scc_mcode_add_u8(mcode, 0xFF);
scc_mcode_add_u8(mcode, 0x15); // reg=010 (CALL), r/m=101 (RIP+disp32)
scc_mcode_add_u32(mcode, disp);
}
/**
* @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__ */