使用内联汇编获取在线OJ平台CPU的信息

目录

1.前置知识

2.LeetCode

3.LintCode

4.牛客


1.前置知识

获取CPU的信息的方法:

1.rax寄存器存储功能号

2.cpuid指令会根据不同的功能号执行不同的任务

1.功能号0: 获取厂商名,此时cpuid将厂商名的ASCII码一次返回到ebx、edx、ecx中,需要将它们存储的ASCII码拼起来,然后调用printf函数打印

2.功能号0x80000002: 获取CPU品牌名的前16个字节,此时cpuid将前16个字节的ASCII码一次返回到eax、ebx、ecx、edx中,需要将它们存储的ASCII码拼起来,然后调用printf函数打印

3.功能号0x80000003,获取CPU品牌名的中间16个字节

4.功能号0x80000004: 获取CPU品牌名的后16个字节

5.功能号0x40000000: 获取虚拟机

可以将寄存器中的返回值存储到栈中,手动添加\0,然后调用printf,注意需要手动平衡栈,例如以下例子:

"sub rsp,15;"
"mov rax,0;"//功能号0,获取厂商
"cpuid;"
"mov dword ptr [rsp],ebx;"
"mov dword ptr [rsp+4],edx;"
"mov dword ptr [rsp+8],ecx;"
"mov byte ptr [rsp+12],0x0;"//添加\0
"add rsp,15;"

根据printf函数打印字符串的System V ABI的调用约定:rdi存储字符串地址,eax清零表示没有浮点参数,之后方可call printf

"lea rdi,[rsp];"
"xor eax,eax;"//eax=0
"call printf;"

2.LeetCode

随便选一道题测试,这里选2235. 两整数相加

测试这个代码:

__attribute__((naked)) int sum(int num1, int num2) 
{
    __asm__ volatile 
    (
        ".intel_syntax noprefix;"
        "sub rsp,100;"
        //----------------------------
        "mov rax,0;"//功能号0,获取厂商
        "cpuid;"
        "mov dword ptr [rsp],ebx;"
        "mov dword ptr [rsp+4],edx;"
        "mov dword ptr [rsp+8],ecx;"
        "mov byte ptr [rsp+12],32;"
        "mov rax,0x80000002;"//功能号0x80000002,获取CPU品牌名前16个字节
        "cpuid;"
        "mov dword ptr [rsp+13],eax;"
        "mov dword ptr [rsp+17],ebx;"
        "mov dword ptr [rsp+21],ecx;"
        "mov dword ptr [rsp+25],edx;"
        "mov byte ptr [rsp+29],32;"
        //----------------------------
        "mov rax,0x80000003;"//功能号0x80000003,获取CPU品牌名中间16个字节
        "cpuid;"
        "mov dword ptr [rsp+30],eax;"
        "mov dword ptr [rsp+34],ebx;"
        "mov dword ptr [rsp+38],ecx;"
        "mov dword ptr [rsp+42],edx;"
        "mov byte ptr [rsp+46],32;"
        //----------------------------
        "mov rax,0x80000004;"//功能号0x80000004,获取CPU品牌名后16个字节
        "cpuid;"
        "mov dword ptr [rsp+47],eax;"
        "mov dword ptr [rsp+51],ebx;"
        "mov dword ptr [rsp+55],ecx;"
        "mov dword ptr [rsp+59],edx;"
        "mov byte ptr [rsp+60],32;"
        //----------------------------
        "mov rax,0x40000000;"//功能号0x40000000,获取虚拟机
        "cpuid;"
        "mov dword ptr [rsp+61],ebx;"
        "mov dword ptr [rsp+65],ecx;"
        "mov dword ptr [rsp+79],edx;"
        "mov byte ptr [rsp+73],32;"
        "mov byte ptr [rsp+74],0x0;"
        "lea rdi,[rsp];"
        "mov eax,0;"
        "call printf;"
        "add rsp,100;"
        //----------------------------  
        "ret;"
        ".att_syntax"
    );
}

只看标准输出:

3.LintCode

随便选一道题测试,这里选3762 · 第一个 C 程序:打印 Hello World

调用上方的sum函数

int main() 
{
    sum(1,2);
    return 0;
}

点击

只看输出数据:

4.牛客

只看stdout:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangcoder

赠人玫瑰手有余香,感谢支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值