關鍵效能路徑、硬體存取、系統底層操作常需內聯組語。本文分享 VC++ `__asm` 區塊實戰技巧:C++ 混合編程、寄存器環境保護、FPU/MMX/SSE/3DNow! 指令集直接調用。
__asm {
// 組合語言指令
mov eax, 1
add eax, ebx
}
區塊內可直接引用 C/C++ 變數名(編譯器自動解析位址)。
void CAlcmemDlg::OnButton3() {
DWORD d = (m_size * 1024 * 1024) / sizeof(DWORD);
DWORD* p = (DWORD*)m_p;
DWORD s;
// ... 進度條初始化 ...
if (NULL != m_p) {
__asm {
mov ecx, d
mov eax, 0
L: mov edx, DWORD PTR p
mov [edx + eax], 1
inc eax
mov s, eax
pushad // 保存所有通用寄存器
}
m_pr.SetValue((float)s); // 呼叫 C++ 方法(會破壞寄存器)
__asm {
popad // 還原寄存器
loop L
}
}
}
關鍵點:`pushad`/`popad` 保存/還原 8 個 32-bit 通用寄存器。若涉及浮點運算,需額外 `pushfd`/`popfd` 保護 EFLAGS,或用 `fxsave`/`fxrstor` 保護 FPU/XMM 狀態。
測試顯示:移除 `m_pr.SetValue` 呼叫並合併 `__asm` 區塊(省去 `pushad`/`popad`),速度明顯提升。**盡量減少 `__asm` 區塊分割**,避免頻繁寄存器保存/還原開銷。
void CAlcmemDlg::OnButton4() {
float f_t = .132f;
float f_s = 0.0f;
__asm {
fld f_s
fld f_s
fld f_s
fld f_t
fadd f_t
fst f_t
// fadd f_s
}
}
| 指令集 | 適用場景 | 備註 |
|---|---|---|
| FPU (x87) | 純量浮點運算 | 堆疊架構,相容性最佳 |
| MMX | 整數 SIMD (64-bit) | 與 FPU 共用寄存器,需 `emms` 清理 |
| SSE/SSE2 | 單/雙精度浮點 SIMD (128-bit) | 獨立 XMM 寄存器,現代 CPU 基礎 |
| SSE3/SSSE3/SSE4 | 擴充 SIMD 指令 | 視 CPU 支援度啟用 |
| AVX/AVX2 | 256-bit 寬向量運算 | 需作業系統支援 YMM 狀態保存 |
| 3DNow! (AMD) | 早期浮點 SIMD | 已棄用,歷史參考 |
程式碼開放分享,作者不承擔使用後果責任。內聯組語屬進階技術,建議具備組語與電腦架構基礎者使用。