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

C程序获取逻辑地址对应物理地址报unsupported instruction `mov'错误求助

这个报错的核心原因是你写的32位x86内联汇编不兼容64位编译环境:64位架构下CR0/CR3/CR4均为64位寄存器,无法直接写入32位的eax寄存器,同时你用unsigned int存储CR寄存器值也会出现高位截断。

优先使用Linux内核已经封装好的CR寄存器读取接口,不需要自行编写内联汇编,兼容性更强,修改后的代码如下:

// 需新增头文件引入CR寄存器读取接口
#include <asm/processor.h>

static int my_seq_show(struct seq_file *m, void *p)
{
        // 变量类型改为unsigned long适配64位寄存器长度
        unsigned long    _cr0,_cr3, _cr4;
    get_pgtable_macro(m);
    printk("the get_pgtable_macro has been output\n");
        if (indata.p !=0 && indata.addr !=0)
        vaddr2paddr(m, indata.addr,indata.p);
        printk("the vaddr2paddr has been done\n");      

    // 替换原有内联汇编为内核原生接口,自动适配32/64位环境
    _cr0 = read_cr0();
    _cr3 = read_cr3();
    _cr4 = read_cr4();
    // 打印格式符调整为%016lX适配64位值输出
    seq_printf(m, "    CR0=0x%016lX", _cr0 );
    seq_printf(m, "    CR3=0x%016lX", _cr3 );
    seq_printf(m, "    CR4=0x%016lX", _cr4 );
    seq_printf(m, "    PE=%lX",  (_cr0 >> 1)&1 );
    seq_printf(m, "    PG=%lX",  (_cr0 >> 31)&1 );
    seq_printf(m, "    PAE=%lX", (_cr4 >> 5)&1 );
    seq_printf(m, "    PSE=%lX", (_cr4 >> 4)&1 );
    seq_printf( m, "\n" );
    
    return  0;
}

如果确实需要自行编写内联汇编实现,64位环境下的写法参考如下:

asm("mov %%cr0, %%rax\n mov %%rax, %0" : "=m" (_cr0) :: "rax");
asm("mov %%cr3, %%rax\n mov %%rax, %0" : "=m" (_cr3) :: "rax");
asm("mov %%cr4, %%rax\n mov %%rax, %0" : "=m" (_cr4) :: "rax");

仍需搭配unsigned long类型的变量使用,否则还是会出现值截断问题,更推荐使用内核原生接口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:36:04