X64 平台 C/C++调用汇编代码

       汇编好久没用了,差不多忘干净了,说句实话,本菜也不会写,临时找了个例子。
建个文本文档,命名为swap.cpp  (记得改下扩展名),内容如下;
int swap(int* a, int* b)
{
  int t;
  t = *a;
  *a = *b;
  *b = t;
  return 1;
}

资源管理器打开 D:\Microsoft Visual Studio 10.0\VC\bin\x86_amd64(这里对照着打开你自己的编译器路径)按住shift键同时单击右键—>在此处打开命令窗口(W),把swap.cpp 拷贝到该目录下,
命令行输入 cl /c /Fa swap.cpp
 

目录下将产生
swap.asm、 swap.obj(可以直接用,不过既然要汇编就不用它了)
打开swap.asm内容如下:
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 

include listing.inc

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC  ?swap@@YAHPEAH0@Z        ; swap
pdata  SEGMENT
$pdata$?swap@@YAHPEAH0@Z DD imagerel $LN3
  DD  imagerel $LN3+58
  DD  imagerel $unwind$?swap@@YAHPEAH0@Z
pdata  ENDS
xdata  SEGMENT
$unwind$?swap@@YAHPEAH0@Z DD 010e01H
  DD  0220eH
; Function compile flags: /Odtp
xdata  ENDS
_TEXT  SEGMENT
t$ = 0
a$ = 32
b$ = 40
?swap@@YAHPEAH0@Z PROC          ; swap
; File d:\microsoft visual studio 10.0\vc\bin\x86_amd64\swap.cpp
; Line 2
$LN3:
  mov  QWORD PTR [rsp+16], rdx
  mov  QWORD PTR [rsp+8], rcx
  sub  rsp, 24
; Line 4
  mov  rax, QWORD PTR a$[rsp]
  mov  eax, DWORD PTR [rax]
  mov  DWORD PTR t$[rsp], eax
; Line 5
  mov  rax, QWORD PTR a$[rsp]
  mov  rcx, QWORD PTR b$[rsp]
  mov  ecx, DWORD PTR [rcx]
  mov  DWORD PTR [rax], ecx
; Line 6
  mov  rax, QWORD PTR b$[rsp]
  mov  ecx, DWORD PTR t$[rsp]
  mov  DWORD PTR [rax], ecx
; Line 7
  mov  eax, 1
; Line 8
  add  rsp, 24
  ret  0
?swap@@YAHPEAH0@Z ENDP          ; swap
_TEXT  ENDS
END

我们来学着上面写个自己的汇编文件,建个记事本,名字mytest.asm,代码如下
.data
.code
t$ = 0
a$ = 32
b$ = 40
my_swap PROC          ; swap
  mov  QWORD PTR [rsp+16], rdx
  mov  QWORD PTR [rsp+8], rcx
  sub  rsp, 24
; Line 4
  mov  rax, QWORD PTR a$[rsp]
  mov  eax, DWORD PTR [rax]
  mov  DWORD PTR t$[rsp], eax  ; t = *a
; Line 5
  mov  rax, QWORD PTR a$[rsp]
  mov  rcx, QWORD PTR b$[rsp]
  mov  ecx, DWORD PTR [rcx]
  mov  DWORD PTR [rax], ecx ;*a = *b
; Line 6
  mov  rax, QWORD PTR b$[rsp]
  mov  ecx, DWORD PTR t$[rsp]
  mov  DWORD PTR [rax], ecx  ;*b = t
; Line 7
  mov  eax, 1
; Line 8
  add  rsp, 24
  ret  0
 my_swap ENDP    
 jiayi PROC 
   mov eax, DWORD PTR [rcx]
   inc eax
   mov DWORD PTR [rcx], eax
     ret 
 jiayi ENDP

end
还是把D:\Microsoft Visual Studio 10.0\VC\bin\x86_amd64目录加入到path环境变量吧,省得每次都进该目录,
写个批处理吧,省得修改文件之后每次编译都要敲,如下
//build-test.bat
ml64 /c mytest.asm
运行批处理,在该目录下生成mytest.obj
新建一个Win32控制台应用程序cc, cc.cpp如下
#include "stdafx.h"

extern "C" void __stdcall jiayi(int* a);
extern "C" int __stdcall my_swap(int* a, int* b);
int _tmain(int argc, _TCHAR* argv[])
{
  int a = 4, b = 5;
  printf("a = %d, b = %d\n", a, b);
  
  jiayi(&a);
  jiayi(&b);
  printf("执行jiayi:\n");
  printf("a = %d, b = %d\n", a, b);

  int ret = my_swap(&a, &b);
  printf("执行my_swap:\n");
  printf("a = %d, b = %d\n", a, b);
  getchar();
  return 0;
}

配置x64平台
点击图片以查看大图

图片名称:	QQ截图20150503173422.png
查看次数:	1
文件大小:	22.6 KB
文件 ID :	97595
在附加依赖项里加入刚才的mytest.obj ,用绝对路径吧,反正测试,哈哈。
点击图片以查看大图

图片名称:	QQ截图20150503163022.png
查看次数:	3
文件大小:	70.5 KB
文件 ID :	97594
运行结果如下:
点击图片以查看大图

图片名称:	QQ截图20150503173642.png
查看次数:	1
文件大小:	18.7 KB
文件 ID :	97596
VS启动调试,下断,右键转到反汇编
名称:  QQ截图20150503173910.png
查看次数: 0
文件大小:  54.4 KB
跟进去可以看到反汇编
点击图片以查看大图

图片名称:	QQ截图20150503165849.png
查看次数:	12
文件大小:	56.9 KB
文件 ID :	97598
呵呵。到此收工,欢迎拍砖!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在C/C++中,可以使用Windows API函数 `GetVersionEx` 或者 `GetProductInfo` 来获取操作系统版本和类型信息。例如: ```c++ #include <iostream> #include <windows.h> int main() { OSVERSIONINFOEX osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&osvi)); std::cout << "Operating system version: " << osvi.dwMajorVersion << "." << osvi.dwMinorVersion << "." << osvi.dwBuildNumber << std::endl; DWORD product_type = 0; GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.wServicePackMajor, osvi.wServicePackMinor, &product_type); std::cout << "Product type: " << product_type << std::endl; return 0; } ``` 在汇编语言中,可以使用`INT 21h`的DOS调用来获取操作系统版本和类型信息。例如: ```assembly .MODEL SMALL .STACK 100h .DATA osver DB 'Operating system verison: $' prodtype DB 'Product type: $' .CODE MAIN PROC MOV AH, 30h ; DOS调用,获取MS-DOS版本信息 INT 21h MOV AH, 30h ; DOS调用,获取MS-DOS扩展版本信息 INT 21h MOV AH, 30h ; DOS调用,获取MS-DOS国际化信息 INT 21h MOV AH, 30h ; DOS调用,获取MS-DOS扩展国际化信息 INT 21h MOV AH, 30h ; DOS调用,获取MS-DOS时钟速度信息 INT 21h MOV AH, 30h ; DOS调用,获取MS-DOS虚拟机类型信息 INT 21h ; 输出结果 LEA DX, osver MOV AH, 09h INT 21h ; 输出操作系统版本信息 ... LEA DX, prodtype MOV AH, 09h INT 21h ; 输出产品类型信息 ... MOV AH, 4Ch INT 21h MAIN ENDP END MAIN ``` 在虚拟机环境中,可以使用`cpuid`指令来获取虚拟机类型信息。例如: ```assembly .MODEL SMALL .STACK 100h .DATA vmtype DB 'Virtual machine type: $' .CODE MAIN PROC MOV EAX, 01h ; 执行CPUID指令,获取CPU信息 CPUID ; 判断是否在虚拟机中 TEST ECX, 1 << 31 ; 检查hypervisor位 JZ not_vm ; 在虚拟机中 LEA DX, vmtype MOV AH, 09h INT 21h ; 输出虚拟机类型信息 ... JMP exit not_vm: ; 不在虚拟机中 ... exit: MOV AH, 4Ch INT 21h MAIN ENDP END MAIN ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值