You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

G++与NASM代码在Rocky 9运行报错,CentOS 7编译运行正常

段错误分析与解决:x86-64汇编CPUID函数在Rocky 9/CentOS Stream 9编译后执行失败

问题根源定位

你遇到的段错误看似触发在mov r8, rdi指令,但寄存器间的移动本身不会引发内存错误,实际问题大概率是内存越界访问,或是新系统/编译器的内存保护机制更严格,导致之前隐藏的问题暴露。

核心问题1:指针类型与内存偏移不匹配

你的C++代码中,函数参数为unsigned long *(x86-64下为8字节指针),但汇编代码中却以4字节(dword)为单位、8字节步长写入数据:

mov         dword [r8], eax
mov         dword [r8+8], ebx
mov         dword [r8+16], ecx
mov         dword [r8+24], edx

如果CPUIDreg.reg是用于存储CPUID 4个32位结果的unsigned int[4]数组(总大小16字节),那么[r8+16]和[r8+24]已经越界访问数组外的内存。CentOS 7的内存布局或栈保护机制宽松,越界未触发错误;但Rocky 9/CentOS Stream 9的内存保护更严格,或启用的-lefence(Electric Fence)工具检测到了越界,直接触发段错误。

核心问题2:Electric Fence兼容性

Rocky 9中的Electric Fence版本对现代编译选项(如默认启用的PIE)支持不佳,可能误判或放大内存访问问题。


解决方案

方案1:修正内存偏移(推荐)

既然CPUID返回的是4个32位寄存器值,应将汇编中的内存偏移改为4字节步长,对应unsigned int[4]数组:

Global get_cpuid_info 
 
get_cpuid_info:                          
           mov r8, rdi   ;#  array addr
           mov r9, rsi   ;#  leaf
           mov r10, rdx  ;#  subleaf

           push        rax              
           push        rbx              
           push        rcx              
           push        rdx              
           mov         rax, r9         
           mov         rcx, r10
           cpuid                        
           mov         dword [r8], eax
           mov         dword [r8+4], ebx  ; 改为+4
           mov         dword [r8+8], ecx  ; 改为+8
           mov         dword [r8+12], edx ; 改为+12
           pop         rdx              
           pop         rcx              
           pop         rbx              
           pop         rax              
           ret  

同时调整C++函数声明的参数类型,匹配实际数组类型:

extern "C" void get_cpuid_info(unsigned int *, const unsigned long func, const unsigned long subfunc);

方案2:确保数组大小足够

如果坚持使用unsigned long *参数,需保证CPUIDreg.reg是至少包含4个unsigned long元素的数组(总大小32字节),确保[r8+24]的访问在数组范围内:

// 定义足够大的数组
unsigned long CPUIDreg_reg[4];
get_cpuid_info(CPUIDreg_reg, 0, 0);

方案3:移除Electric Fence测试

暂时去掉编译命令中的-lefence选项,验证是否是工具兼容性问题:

g++ -L../../lib -ltsx64 -pthread -o cpuinfo cpuinfo.o test1.o

方案4:显式关闭PIE编译(可选)

Rocky 9的GCC默认启用PIE(位置无关可执行文件),如果汇编代码对PIE兼容性不佳,可显式添加-no-pie编译选项:

g++ -c -Wall -g -D_DEBUG -Dx86_64 -pthread -no-pie -o cpuinfo.o cpuinfo.cpp
g++ -L../../lib -ltsx64 -pthread -no-pie -o cpuinfo cpuinfo.o test1.o

内容的提问来源于stack exchange,提问作者Jonathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:41:05