2.5 OpenEuler 中C与汇编的混合编程
2.5 OpenEuler 中C与汇编的混合编程
任务详情
- 在X86_64架构下实践2.5中的内容,提交代码和实践截图
- 把2.5的内容在OpenEuler中重新实践一遍,提交相关代码和截图
任务一x86_64实现
操作环境:Ubuntu Kylin(x86_64)
2.5.1用汇编代码编程
将C代码编译成汇编代码
a.c file
#include <stdio.h>
extern int B();
int A(int x, int y){
int d, e, f;
d = 4;
e = 5;
f = 6;
f = B(d,e);
}
a.s file
A:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $4, -20(%ebp)
movl $5, -16(%ebp)
movl $6, -12(%ebp)
subl $8, %esp
pushl -16(%ebp)
pushl -20(%ebp)
call B
addl $16, %esp
movl %eax, -12(%ebp)
nop
leave
ret
2.5.2用汇编语言实现函数
示例2.2
获取CPU寄存器
s.s file
.global get_esp, get_ebp
get_esp:
movl %esp, %eax
ret
get_ebp:
movl %ebp, %eax
ret
print.c
#include <stdio.h>
int main(){
int ebp, esp;
ebp = get_ebp();
esp = get_esp();
printf("ebp=%8x esp=%8x\n", ebp, esp);
}
编译运行截图
示例2.3
用汇编语言编写mysum函数
mysum.s
.code32
.text
.global mysum, printf
mysum:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl 12(%ebp), %eax
movl %ebp, %esp
pop %ebp
ret
sum.c
#include <stdio.h>
int main(){
int a, b, c;
a = 123;
b = 456;
c = mysum(a, b);
printf("c=%d\n",c);
}
编译运行截图
2.5.3从汇编中调用C函数
示例2.4:访问全局变量并调用printf()
sub.s
.text
.global sub, a, d, printf
sub:
pushl %ebp
movl %esp, %ebp
pushl b
pushl a
pushl $fmt
call printf
addl $12, %esp
leave
ret
.data
fmt: .asciz "a=%d b=%d\n"
submain.c
#include <stdio.h>
int a, b;
int main(){
a = 100;
b = 200;
sub();
}
编译运行截图
任务二OpenEuler实现
因为openeuler系统不支持32位,所以需要将32位汇编代码改为64位汇编;
根据书2.4.3可知在64位模式下寄存器扩展,调用函数时参数依次进入edi,esi,edx,ecx,r8d,r9d不需要再在调用前进行压栈操作;
64位模式保留红色栈区128字节,即默认进行指令subl $128, %rsp,所以一般情况下不进行压栈操作,直接对栈帧%rbp进行操作即可;
进入叶过程中需要对寄存器中传入参数保留在栈中;
因为在64位模式下,对寄存器为64位操作,部分指令需要改变
操作环境:OpenEuler(wsl)
2.5.1用汇编代码编程
将C代码编译成汇编代码
a.c file
#include <stdio.h>
extern int B();
int A(int x, int y){
int d, e, f;
d = 4;
e = 5;
f = 6;
f = B(d,e);
}
a.s file
A:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
movl %edi, -20(%rbp)
movl %esi, -24(%rbp)
movl $4, -4(%rbp)
movl $5, -8(%rbp)
movl $6, -12(%rbp)
movl -8(%rbp), %edx
movl -4(%rbp), %eax
movl %edx, %esi
movl %eax, %edi
movl $0, %eax
call B
movl %eax, -12(%rbp)
leave
ret
2.5.2用汇编语言实现函数
示例2.2
获取CPU寄存器
s.s file
.globl get_esp, get_ebp
get_esp:
movq %rsp, %rax
ret
get_ebp:
movq %rsp, %rax
ret
print.c
#include <stdio.h>
int main(){
int ebp, esp;
ebp = get_ebp();
esp = get_esp();
printf("rbp=%8x rsp=%8x\n", ebp, esp);
}
编译运行截图
示例2.3
用汇编语言编写mysum函数
mysum.s
.text
.global mysum, printf
mysum:
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -8(%rbp), %eax
addl -4(%rbp), %eax
popq %rbp
ret
sum.c
#include <stdio.h>
int main(){
int a, b, c;
a = 123;
b = 456;
c = mysum(a, b);
printf("c=%d\n",c);
}
编译运行截图
2.5.3从汇编中调用C函数
示例2.4:访问全局变量并调用printf()
sub.s
.text
.global sub, a, d, printf
sub:
pushq %rbp
movq %rsp, %rbp
movl b, %edx
movl a, %esi
movl $fmt, %edi
call printf
leave
ret
.data
fmt: .asciz "a=%d b=%d\n"
submain.c
#include <stdio.h>
int a, b;
int main(){
a = 100;
b = 200;
sub();
}
编译运行截图
2.5 OpenEuler 中C与汇编的混合编程的更多相关文章
- ARM中C和汇编混合编程及示例(转)
在嵌入式系统开发中,目前使用的主要编程语言是C和汇编,C++已经有相应的编译器,但是现在使用还是比较少的.在稍大规模的嵌入式软件中,例如含有OS,大部分的代码都是用C编写的,主要是因为C语言的结构比较 ...
- ARM汇编与C混合编程
GNU内联汇编 内联汇编即在C中直接使用汇编语句进行编程,使程序可以在C程序中实现C语言不能完成的一些工作,例如,在下面几种情况中必须使用内联汇编或嵌入型汇编 程序中使用饱和算术运算(Saturati ...
- Android程序中,内嵌ELF可执行文件-- Android开发C语言混合编程总结
前言 都知道的,Android基于Linux系统,然后覆盖了一层由Java虚拟机为核心的壳系统.跟一般常见的Linux+Java系统不同的,是其中有对硬件驱动进行支持,以避开GPL开源协议限制的HAL ...
- Cortex-M3中C与汇编的交互
以下内容摘自<ARM Cortex-M3权威指南> 概览 在CM3 上编程,既可以使用C 也可以使用汇编.可能还有其它语言的编译器,但是大多数人还是 ...
- 理解ATL中的一些汇编代码(通过Thunk技术来调用类成员函数)
我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以 ...
- KEIL C51程序中如何嵌入汇编
模块内接口:使用如下标志符:#pragma asm汇编语句#pragma endasm注意:如果在c51程序中使用了汇编语言,注意在Keil编译器中需要激活Properties中的“Generate ...
- Linux C中内联汇编的语法格式及使用方法(Inline Assembly in Linux C)【转】
转自:http://www.linuxidc.com/Linux/2013-06/85221p3.htm 阅读Linux内核源码或对代码做性能优化时,经常会有在C语言中嵌入一段汇编代码的需求,这种嵌入 ...
- x64汇编第四讲,c / C++中调用x64汇编
目录 x64汇编第四讲,c / C++中调用x64汇编 一丶简介 1.说明 二丶C/C++调用 asm64.asm函数. 1.配置asm参与生成 2.给Asm文件添加函数代码 3.C/C++调用asm ...
- C51与汇编混合编程详解
C51和汇编混合编程(1)-C语言中嵌入汇编 1.在 C文件中要嵌入汇编代码片以如下方式加入汇编代码: #pragma ASM ;Assembler Code Here #pragma ENDASM ...
- c语言环境初始化&c语言和汇编混合编程
bootloader通常会分为两个阶段:第一阶段采用汇编语言来编写,主要是一些核心的初始化工作(内存,时钟的初始化),第二阶段使用C语言来编写,主要是它会完成一些板载硬件的初始化(串口,网口)然后其启 ...
随机推荐
- 线程、GIL、协程
1.多进程实现TCP服务端并发 1.之前我们学习了一个服务端对应一个客户端的操作,但是我们无法实现一个服务端对应多个客户端的操作.因此我们需要在pycharm的右上角点击倒三角,选择Edit Conf ...
- maven打包失败 Cannot create resource output directory
转https://blog.csdn.net/wuyuanshun/article/details/103097447 maven clean后打包出现Cannot create resource o ...
- 云萌 V2.6.3.0 win10,win11 Windows永久激活工具
Windows如果一直不激活,其实用起来问题也不大,除了无法修改壁纸.颜色.锁屏.主题以及无法使用微软账号的同步功能等之外,绝大多数的基本功能都可以正常使用.不过该激活还是得激活的.别的不说,就桌面右 ...
- 项目与自身毕设对比整理规划6 330 done
3.30 没用呢- - 功夫不负有心人啊啊啊啊啊啊啊啊啊啊啊啊啊啊 成功了- - 但是很可恶 需要把数据返回然后放在那个文件里面才可以 现在就是问题就是返回数据的时候需要把这个文件存成数据接口 fin ...
- 国际财务系统基于ShardingSphere的数据分片和一主多从实践
作者:京东物流 张广治 1 背景 传统的将数据集中存储至单一数据节点的解决方案,在性能和可用性方面已经难于满足海量数据的场景,系统最大的瓶颈在于单个节点读写性能,许多的资源受到单机的限制,例如连接数. ...
- DVWA靶场实战(十四)——JavaScript
DVWA靶场实战(十四) 五.Java Script: 1.漏洞原理: 这里的JavaScript其实是JavaScript Attack也就是JS攻击.JavaScript是一种基于对象和事件驱动的 ...
- 给力的Zstack云主机
合肥光源储存环纵向震荡可视化展示初步结果 前两天做好上面的可视化展示后,想着顺道把那个时间的二维图分析结果给出来吧,就又把纵向震荡的每个束团的频谱和相位顺道可视化显示出来,给计算这些结果的云主机又加点 ...
- BI工具术语表大全:从字母A-Z全面收录
谈到商业智能行业,变革是不可避免的.为了跟上步伐,各种各样的BI 解决方案正在快速迭代更新,以满足企业的数字化需求,那么市场上BI 工具种类繁杂,到底如何选择适合功能全面.满足自己企业运转情况的.合适 ...
- Nacos集群搭建(三个节点)
Nacos集群安装 一,在每台服务器上安装nacos 1,准备安装包 github下载点 2,在/usr/local/目录下创建一个文件夹用于上传和解压Nacos cd /usr/local/ # ...
- Java第四讲动手动脑
1. 在以上的代码中,main方法调用的是public void println(Object x),这一方法调用了String类的valueOf方法,valueOf方法内部调用Object. toS ...