欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

C++内嵌汇编 教程1

发布时间:2024/8/1 43 豆豆
生活随笔 收集整理的这篇文章主要介绍了 C++内嵌汇编 教程1 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475
注:本文的所有代码是在我自己的VS2008中测试的,由于环境的差别,不能保证能在所有的编译器上运行。

1.内嵌汇编介绍

在C++中,可以通过__asm关键字来嵌入汇编语言。例如

int main(){\_\_asm{//汇编!mov eax,0}return 0; }

2.汇编版本Hello, World!

我们知道,在C++中,可以使用printf函数来输出。(如果使用cout,需要使用运算符重载等技术,在这里反而不方便)

提示:汇编中,调用函数的指令叫做CALL。函数的参数是保存在栈中的。

那么我们可以开始写了。首先,先看看C++正常版本的:

#include #includeconst char *s1="Hello, World\n",*s2="pause"; int main(){printf(s1);system(s2);return 0; }

为了方便,我们先把正常版本反汇编一下,结果是:

printf(s1); 00BD13CE mov esi,esp 00BD13D0 mov eax,dword ptr [s1 (0BD7038h)] 00BD13D5 push eax 00BD13D6 call dword ptr [\_\_imp\_\_printf (0BD82C4h)] 00BD13DC add esp,4 00BD13DF cmp esi,esp 00BD13E1 call @ILT+315(\_\_RTC\_CheckEsp) (0BD1140h)

第一句,mov esi,esp 为了后面检查栈是否正常用第二句,mov eax,dword ptr[s1] 括号中的0BD7038h是地址,不要管他,意思是把地址放到eax中去第三句,push eax 把刚才放进eax的地址放入栈, 实际就是把参数放入栈

第四句,call dword ptr [__imp__printf]__imp__printf是printf函数编译后的结果,下划线开头表示这是一个函数我们平时写内联汇编的时候直接写printf即可

第五句,add esp,4其实是手动平栈,之前往栈里面放了4字节的s1,现在把esp指针也就是栈顶指针下移(栈从高地址往低地址),平栈

最后两句不管它,就是保证esi和esp相等,因为之前手动平了栈,结合第一句,这里应该是相等的,不写应该也没事

最终的内联汇编应该是这样:

#include #includeconst char *s1="Hello, World\n",*s2="pause"; int main(){\_asm{mov eax,dword ptr [s1]push eaxcall dword ptr [printf]add esp,4mov eax,dword ptr[s2]push eaxcall dword ptr [system]add esp,4}return 0; }

运行结果正常。

3.内联汇编A+B

A+B问题,同时需要使用scanf和printf

首先注意一点,函数的参数在栈中是倒着存放的。(注:这个C标准没有规定,但是汇编语言本身就是非常依赖环境的一个东西,所以暂且不管它)

例如

scanf("%d %d",&a,&b);

如果翻译成汇编,应该是这样(下面的是伪代码)

push &b push &a push "%d %d" call scanf

然后我们就可以开始写了。

scanf的部分,注意最前面两个参数,由于放入的是地址,所以不能使用MOV指令而是要使用LEA指令

lea eax,[a]

表示把a的地址放入eax中。

其他部分没有什么难度,注意最后平栈的时候,add esp到底加上多少,加上的是每个参数的大小相加。

例如scanf,每个都是4字节的地址,总共就是12字节。

完整代码

#include #includeconst char *s1="%d%d",*s2="%d\n",*s3="pause"; int a,b; int main(){\_asm{lea eax,[b]push eaxlea eax,[a]push eaxmov eax,dword ptr [s1]push eaxcall dword ptr [scanf]add esp,12mov eax,[a]add eax,[b]push eaxmov eax,dword ptr [s2]push eaxcall dword ptr [printf]add esp,8mov eax,dword ptr [s3]push eaxcall dword ptr [system]add esp,4}return 0; }

总结

以上是生活随笔为你收集整理的C++内嵌汇编 教程1的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。