首页
社区
课程
招聘
[求助]Windows 64位C++调用独立汇编函数的问题
发表于: 2017-11-23 11:47 4533

[求助]Windows 64位C++调用独立汇编函数的问题

2017-11-23 11:47
4533
汇编新人,求汇编大神赐教!想把之前Windows 32位的C++程序升级成64位,但64位不再支持内联汇编,所以想把C++中的全部内联的汇编放到一个独立汇编文件中,然后导出函数给C++调用。本人熟悉C++,但汇编只是了解,大学时只学过单片机汇编,现在都忘记了,最近又大概学了下32和64位汇编,感觉要实现的个很费力,现在已经能导出一些简单的函数给C++调用,但想搞些复杂的就不是编译不过就是运行崩溃。像怎么把多个寄存器的值或多个计算结果传给C++用,如获取CPUID、循环位移等函数的实现。
获取CPUID的C++代码如下:
extern "C"
{
void MY_CPUID(DWORD dwVEax, DWORD &dwDEax, DWORD &dwDEbx, DWORD &dwDEcx, DWORD &dwDEdx);
}

struct cpuinfo
{
DWORD eax;
DWORD ebx;
DWORD ecx;
DWORD edx;
};
cpuinfo cpuid(DWORD veax)
{
// 因为嵌入式的汇编代码不能识别 类成员变量
// 所以定义四个临时变量作为过渡
DWORD deax=0;
DWORD debx=0;
DWORD decx=0;
DWORD dedx=0;

__asm
{
mov eax, veax;//将输入参数移入eax
cpuid;//执行cpuid
mov deax, eax;//以下四行代码把寄存器中的变量存入临时变量
mov debx, ebx
mov decx, ecx
mov dedx, edx
}

cpuinfo info;
info.eax = deax; // 把临时变量中的内容放入类成员变量
info.ebx = debx;
info.ecx = decx;
info.edx = dedx;
return info;
}

int main()
{
cpuinfo info;
MY_CPUID(1  , cpuinfo .eax , cpuinfo .ebx , cpuinfo .ecx , cpuinfo .edx);
return 0;
}
汇编代码如下:
PUBLIC MY_CPUID
MY_CPUID PROC
mov QWORD PTR [rsp+32], r9
mov QWORD PTR [rsp+24], r8
mov QWORD PTR [rsp+16], rdx
mov DWORD PTR [rsp+8], ecx
sub  rsp, 40

mov eax, ecx;//将输入参数移入eax
cpuid;//执行cpuid
mov DWORD PTR [rdx], eax;//以下四行代码把寄存器中的变量存入临时变量
mov DWORD PTR [r8], ebx
mov DWORD PTR [r9], ecx
mov rax, QWORD PTR [rsp+32]
mov DWORD PTR [rax], edx

add rsp, 40
ret
MY_CPUID ENDP

循环位移 代码如下:
bool encryption_rotate::encrypt( const char * in_buffer,unsigned in_len,const char ** out_buffer,unsigned &out_len,const void * key)
{
alloc_buffer(in_len);

unsigned long count = in_len/sizeof(unsigned long);

const unsigned long * in_buf = (const unsigned long *)in_buffer;
const unsigned long * out_buf= (const unsigned long *)_encrypt_buffer;
const unsigned char * key_buf= (const unsigned char *)((key_info*)key)->_key_data;

// C++没有循环移位指令,故用内联汇编实现,为了速度更快你可以加上双流水线处理
_asm
{
MOV EBX,0
MOV ECX,count
START:
JCXZ DONE                   ; for ( int i=count;i!=0;--i )
MOV EDX,in_buf              ; value = *in_buf
MOV EAX,dword ptr[EDX]
MOV EDX,key_buf             ; cl = key_buf[ebx%4]
XOR EAX,dword ptr [EDX]     ; value ^= _key_data
PUSH ECX
MOV CL,byte ptr [EDX+EBX]      
ROL EAX,CL                  ; value << cl
POP ECX
INC EBX
AND EBX,3H                  ; ebx = (ebx+1)%4
MOV EDX,out_buf             ; *out_buf = value
MOV dword ptr [EDX],EAX
ADD in_buf,TYPE in_buf      ; ++in_buf
ADD out_buf,TYPE out_buf    ; ++out_buf
LOOP START
DONE:
};

memcpy((void *)out_buf,(void *)in_buf,in_len%sizeof(unsigned long));

out_len = in_len;
*out_buffer = _encrypt_buffer;

return true;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (13)
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
坐等高手解答啊
2017-11-23 11:51
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
汇编执行mov  DWORD  PTR  [rdx],  eax;//以下四行代码把寄存器中的变量存入临时变量这条就会崩溃,操作下面的2句mov  DWORD  PTR  [r8],  ebx
mov  DWORD  PTR  [r9],  ecx都不会,rdx寄存器也是易变的
2017-11-23 11:53
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
烦请大神们照着我说的意思封装成可以编译和运行的汇编函数来,感觉好麻烦,也许是自己不太懂汇编的原因
2017-11-23 12:01
0
雪    币: 12848
活跃值: (9147)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
5
#include  <intrin.h>
void  __cpuidex(int[4],  int,  int)
2017-11-23 13:16
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
hzqst #include void __cpuidex(int[4], int, int)
这个对获取CPUID确实可以,但其它的可能就没有相关的内部函数可用了
2017-11-23 15:46
0
雪    币: 1176
活跃值: (1264)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
7
你这代码看起来太乱  排下版    或者发源码我给编译下 
2017-11-23 16:05
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
Tennn 你这代码看起来太乱 排下版 或者发源码我给编译下
多谢大神,我自己写了个测试代码帮看看,我用的是VS2017,项目我设置成生成汇编,那个Test函数我是为了分析VS生成的汇编以便仿照着写
上传的附件:
2017-11-23 22:16
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
Tennn 你这代码看起来太乱 排下版 或者发源码我给编译下
就先帮我看看我的获取CPUID的测试代码,如果有时间也把那个循环位移的代码也照着封装下
2017-11-23 22:18
0
雪    币: 1176
活跃值: (1264)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
10
魔幻明 就先帮我看看我的获取CPUID的测试代码,如果有时间也把那个循环位移的代码也照着封装下
你这不是能编过吗 
2017-11-23 22:30
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
Tennn 你这不是能编过吗
运行会崩溃啊
2017-11-24 10:15
0
雪    币: 1176
活跃值: (1264)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
12
魔幻明 运行会崩溃啊
没有啊  我昨晚编译运行了  vs2015  x64  debug  并没有崩溃
2017-11-24 10:56
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
Tennn 没有啊 我昨晚编译运行了 vs2015 x64 debug 并没有崩溃
mov  DWORD  PTR  [rdx],  eax这句崩溃,我大概知道原因了,在cpuid指令执行之前,rdx存了第二个参数即dwDEax变量的地址值,但执行cpuid时,会把执行结果写到rdx,后面对rdx存的地址进行写数据时自然地址非法了
2017-11-24 15:41
0
雪    币: 1485
活跃值: (1135)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
x64可以在工程中加入汇编源码文件,代替写你要的内联汇编,用c调用即可。
2018-2-10 20:14
0
游客
登录 | 注册 方可回帖
返回
//