- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
C语言函数内可以自定义一段汇编代码,在GCC编译器中使用 asm 或 __asm__ 关键词定义一段汇编代码,并可选添加volatile关键字,表示不要让编译器优化这段汇编代码.
内嵌汇编代码格式如下:
__asm__
(
"汇编代码"
:输出描述
:输入描述
:修改描述
);
汇编代码部分是一个字符串,嵌入的汇编代码使用此字符串存储,多个汇编代码语句之间使用;符号隔开,字符串可以换行存储,换行存储方式如下:
__asm__
(
"mov eax,ecx; \
add eax,ebx;"
);
或者:
__asm__
(
"mov eax,ecx;"
"add eax,ebx;"
);
注: 1.汇编代码中16进制数据只能使用0x前缀,不能使用h后缀。 2.指定内存数据长度时,使用 word prt 关键词,不能省略 prt。 3.内嵌汇编代码默认使用AT&T语法,若使用inter语法则需要在编译时添加如下参数:-masm=intel,本文使用inter汇编语法.
若汇编代码执行完毕后需要将寄存器、内存单元中的数据保存在C语言代码定义的局部变量中,则需要在输出描述部分定义寄存器或内存单元与局部变量的绑定关系,绑定代码格式如下:
#include <stdio.h>
int main()
{
int i;
__asm__
(
"mov eax,1; \
mov ebx,2; \
add eax,ebx;"
:"=a"(i) //输出描述部分,"=a"表示输出eax寄存器,(i)表示使用变量i接收输出数据
);
printf("%d\n", i);
return 0;
}
输出描述部分使用简写代码表示要输出的寄存器或内存单元,常用代码如下: a,表示ax系寄存器 b,表示bx系寄存器 c,表示cx系寄存器 d,表示dx系寄存器 S,表示si系寄存器 D,表示di系寄存器 r,表示自动分配的寄存器 m,表示自动分配的内存单元 g,表示自动分配的寄存器或内存单元 。
绑定的局部变量可以使用指针指定.
#include <stdio.h>
int main()
{
int i;
int *p1 = &i;
__asm__
(
"mov eax,1; \
mov ebx,2; \
add eax,ebx;"
:"=a"(*p1)
);
printf("%d\n", i);
return 0;
}
输入描述用于将局部变量与指定的寄存器或内存单元绑定,绑定的变量会首先复制到对应的寄存器或内存单元,然后再执行汇编代码.
#include <stdio.h>
int main()
{
int i1, i2, i3;
printf("输入两个整数\n");
scanf("%d%d", &i1, &i2);
__asm__
(
"add eax,ebx;"
:"=a"(i3) //输出描述部分,eax写入i3
:"a"(i1), "b"(i2) //输入描述部分,i1写入eax,i2写入ebx
);
printf("两数相加结果为:%d\n", i3);
return 0;
}
修改描述用于告知编译器哪些寄存器、内存单元被汇编代码修改过,让编译器在编译代码时对这些寄存器或内存单元进行保护,当然也可以手动进行保护,在使用寄存器之前首先将其入栈存储,在汇编代码末尾处还原寄存器.
修改描述注意事项: 1.若被修改的寄存器在输出描述、输入描述中记录过,则无需在修改描述中重复指定,编译器会自动处理。 2.若修改了内存单元,则应该在此部分定义"memory"。 3.若修改了标志寄存器,则应该在此部分定义"c".
#include <stdio.h>
int main()
{
int i1, i2, i3;
printf("输入两个整数\n");
scanf("%d%d", &i1, &i2);
__asm__
(
"add eax,ebx; \
mov edx,3; \
imul ecx,edx" //ecx与edx相乘仅做示例,没有实际作用
:"=a"(i3) //输出描述部分,eax写入i3
:"a"(i1), "b"(i2) //输入描述部分,i1写入eax,i2写入ebx
:"ecx", "edx" //修改描述部分,告知编译器ecx、edx被修改过,并且没有在输入输出描述中记录
);
printf("两数相加结果为:%d\n", i3);
return 0;
}
在汇编代码中存储数据时可以让编译器自动分配寄存器或内存,汇编代码使用“%数字”的方式调用编译器自动分配的寄存器或内存,比如:%0、%1、%2,这些名称称为占位符,占位符可以不按顺序定义.
占位符可以与输入输出描述中的局部变量绑定,绑定顺序为局部变量在输入输出描述中出现的顺序,%0绑定第一个变量、%1第二个、%2第三个.
#include <stdio.h>
int main()
{
int i1, i2, i3;
printf("输入两个整数\n");
scanf("%d%d", &i1, &i2);
__asm__
(
"add %1,%2; \
mov %0,%1"
:"=m"(i3) //输出描述部分,%0写入i3,这里使用m,表示让编译器自动分配内存单元存储绑定的i3
:"r"(i1), "r"(i2) //输入描述部分,i1写入%1,i2写入%2,这里使用r,表示让编译器自动分配寄存器存储绑定的i1、i2
);
printf("两数相加结果为:%d\n", i3);
return 0;
}
上面汇编代码中三个变量出现顺序是i3、i1、i2,%0绑定i3,%1绑定i1,%2绑定i2.
在汇编代码中调用全局变量无需进行任何设置,直接使用变量名即可,编译器会自动转换为对应的内存地址.
#include <stdio.h>
int i1, i2;
int main()
{
printf("输入两个整数\n");
scanf("%d%d", &i1, &i2);
__asm__ __volatile__
(
"push rax; \
mov eax,i1; \
add eax,i2; \
mov i1,eax; \
pop rax;"
);
printf("两数相加结果为:%d\n", i1);
return 0;
}
上述汇编代码中,全局数据的名称无需放在[]符号内,但是若将一个立即数写入内存数据,则需要使用如下代码:mov dwort ptr[i1], 5,
。
最后此篇关于09.C语言内嵌汇编代码的文章就讲到这里了,如果你想了解更多关于09.C语言内嵌汇编代码的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
如果 Rmd 文件中的 R 代码重复使用相同的变量名,则内联 r 表达式似乎返回此变量的最后一个值,而不管内联表达式的位置。除了确保不在文档的不同部分重复使用相同的变量名称之外,是否可以避免这种行为?
我希望多行文本像单个文本 block 一样环绕,例如下面的“Source”和“DEC”字段,而不使用表格。 我想我应该能够使用 inline-block 来让它工作,但我没有成功。 下面是我正在使用的
我不熟悉Inline Anchor styles(link) ,怎样才能让它的作品展现时尚呢? Javascript/JQuery 编码或遗漏了什么? [ http://codepen.io/anon
我正在尝试将嵌入式 ruby 添加到我的 css 样式宽度标签中。 这是目前代码的样子: %"> 不确定我是否只是搞砸了目标变量,或者我的 float 是否已关闭(它正在打印正确的百分比),但
我想制作一个时间轴,但它的结构已损坏。我认为这是因为 display:inline,如果我试图对我的网站这样做,它会破坏它。display: inline-block 也让它变得有趣。 我尝试将 di
这个问题在这里已经有了答案: How to remove the space between inline/inline-block elements? (41 个回答) 关闭 7 年前。 不确定我
我正在尝试使用嵌入式 UIStackViews 来获得如下所示的内容: Label1 ----------------Label2 Label3 -- 所以我在一个水平 UIStackView 中有
是否可以在使用内联 CSS 的同时创建一个盒子模型 hack? 例如: 谢谢! 最佳答案 您也可以在内联样式中使用“前缀”技巧: 只需确保将 IE hack 放在样式属性的末尾即可。然而,我同意尽
有没有人有什么技巧可以在页面上对齐这两个按钮?默认情况下,iframe 版本的 facebook like 按钮显示在 google plus 按钮下方,反之亦然。是否有任何 CSS 技巧可以使它们保
这就是我想要实现的目标。我有一个运行 Suricata 的内联 linux 盒子,能够丢弃数据包。这适用于将所有流量放到 NFQUEUE 0 上然后设置 suricata 监听的标准方法。 我正在编写
我目前正在将元素中的一个页面导出到 Excel,这将不允许链接外部内容,例如外部 CSS。 我想要实现的是一种在我的 View 中包含 CSS 文件但直接从 Visual Studio 自动缩小的 C
在一个两列的框中(column-count: 2),CSS 设置break-inside: avoid 应该避免一些内容从一列中断到其他。这在 Firefox 和 Chrome 中运行良好(使用适当的
几乎完成了我的登录脚本,只需要帮助寻找替代方法: return (mysql_result($query, 0) == 1) ? true : false; 查询: $query = mysqli_q
我正在尝试获取一个具有嵌入式 Tomcat 服务器的 Spring Boot jar,以在运行时加载外部 war 。我正在尝试使用此 post 中显示的技术来执行此操作. Spring Boot应用中
我正在开发 Spring Boot 1.4 应用程序,并且正在为我的 Rest 端点编写集成测试。我正在使用新的测试注释,如下所示: @RunWith(SpringRunner.class) @Spr
我是一名优秀的程序员,十分优秀!