- 在argparse库中将所有null指针常量替换为nullptr - 更新头文件和源文件中的指针初始化和比较操作 - 修改测试文件中的相关断言检查 - 更新AST定义文件中的注释说明
2532 lines
70 KiB
C
2532 lines
70 KiB
C
/**
|
||
* @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 位添加 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);
|
||
}
|
||
|
||
// ==================== 符号/零扩展加载(内存操作数) ====================
|
||
|
||
/**
|
||
* @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__ */
|