当前位置: 首页 > news >正文

使用内联汇编获取在线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:

http://www.dtcms.com/a/329644.html

相关文章:

  • 玩转Docker | 使用Docker部署WordPress网站服务
  • 基本计算器 II
  • 回归分析预测原神深渊血量
  • 【金仓数据库产品体验官】_从实践看金仓数据库与 MySQL 的兼容性
  • Windows系统设置内外网同时访问(小白友好版)
  • Docker部署 Neo4j 及集成 APOC 插件:安装与配置完整指南(docker-compose)
  • 【Android】RecyclerView多布局展示案例
  • Kubernetes(K8S)中,kubectl describe node与kubectl top pod命令显示POD资源的核心区别
  • C语言:队列的实现和剖析
  • Spring Boot 整合 Thymeleaf 模板引擎:从零开始的完整指南
  • 攒钱学概论:5、创业术
  • Gemma 3 报告中的蒸馏
  • PHP imagick扩展安装以及应用
  • 16_基于深度学习的道路缺陷检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • 自动驾驶轨迹规划算法——Apollo EM Planner
  • 从0开始配置conda环境并在PyCharm中使用
  • 8.13打卡 DAY 41 简单CNN
  • 对比学习中核心损失函数的发展脉络
  • 内存泄漏系列专题分析之三十三:cameraserver ION骤降成-1导致内存占用超标
  • 《Power Voronoi图的数学原理》
  • Nginx学习笔记(六)—— Nginx反向代理
  • CSS保持元素宽高比,固定元素宽高比
  • Socket 套接字的学习--UDP
  • 设计秒杀系统从哪些方面考虑
  • 服务器安全检测和防御技术
  • 符合实时AUTOSAR OS的形式化设计和验证方法
  • WPF的c1FlexGrid的动态列隐藏和动态列名设置
  • AI企业培训系统构建指南
  • 在 Conda 环境下编译 C++ 程序时报错:version `GLIBCXX_3.4.30‘ not found
  • 数据结构:队列(Queue)与循环队列(Circular Queue)