🍃方法总结
C/C++中内嵌汇编(Visual Studio 2019)
案例1
#include <stdio.h> int main() { int a = 0, b = 0, c = 0; __asm { /*push eax s*/ mov a, 1000 mov b, 200 mov c, 1 /*mov eax, a add eax, b sub eax, c mov a, eax */ /*pop eax*/ } /*__asm mov a,1000*/ printf("a=%d\nb=%d\nc=%d\n", a, b, c); return 0; }
案例2-内联汇编
内联汇编示例:
Hello, World为例:
#include #include const char *s1="Hello, World\n",*s2="pause"; int main(){ printf(s1); system(s2); return 0; }
内联汇编版本:
#include <stdio.h> #include<Windows.h> const char* s1 = "Hello, World\n", * s2 = "pause"; int main() { __asm { mov eax, dword ptr[s1] push eax call dword ptr[printf] add esp, 4 mov eax, dword ptr[s2] push eax call dword ptr[system] add esp, 4 } return 0; }
内联汇编A+B
#include <stdio.h> #include<Windows.h> const char *s1="%d%d",*s2="%d\n",*s3="pause"; int a,b; int main(){ __asm{ lea eax,[b] push eax lea eax,[a] push eax mov eax,dword ptr [s1] push eax call dword ptr [scanf] add esp,12 mov eax,[a] add eax,[b] push eax mov eax,dword ptr [s2] push eax call dword ptr [printf] add esp,8 mov eax,dword ptr [s3] push eax call dword ptr [system] add esp,4 } return 0; }
基础讲解
因为在Visual C++中使用内联汇编不需要额外的编译器和联接器,且可以处理Visual
C++中不能处理的一些事情,同时可以使用在C/C++中的变量,所以非常方便。
内联汇编代码不易于移植,如果你的程序打算在不同类型的机器(比如x86和Alpha)上运行,应当尽量避免使用内联汇编,这时可以使用MASM,因为MASM支持更方便的宏指令和数据指示符。
__asm语法
__asm关键字用来调用内联汇编,可以出现在任何合法的C或C++声明中。它不能单独出现,后面必须有汇编指令,可以是一条汇编指令、大括号括起来的一组代码,或者至少是大括号括起来的空代码。术语“__asm块”指的是任何单独的一条指令或一组指令,可以不包括在大括号里。
第一种语法格式:
__asm 汇编指令
第二种语法格式:
__asm { 汇编指令列表 }
例如,下面的代码是一个简单的大括号里的__asm块:
__asm { mov al, 4 mov dx, 0xB008 out dx, al }
另外,在每一条汇编指令前加上__asm,与前面的方法是一样的作用。例如:
__asm mov al, 4 __asm mov dx, 0xB0008 __asm out dx, al
上面的两个例子所生成的代码是相同的,但是在括号里的__asm块这种方式更具优势,因为大括号可以使汇编指令很清楚地和C或C++代码分开,避免了无意义的__asm关键字重复。另外,大括号还可以避免引起歧义。如果想把C或C++代码和__asm块放在同一行,则必须把这个__asm块放在括号里。如果没有括号,编译器就不能确定汇编代码结束和C或C++代码起始的位置。
另外,由于大括号里的语句和一般的MASM语句格式一样,所以可以很方便地从现有的MASM源程序里复制。
不像C或C++中的"{}",__asm块中的"{}"不会影响C或C++变量的作用范围。同时,__asm块可以嵌套,嵌套也不会影响变量的作用范围。
转载于:https://www.cnblogs.com/smart-zihan/p/11315436.html