2.5 OpenEuler 中C与汇编的混合编程

任务详情

  1. 在X86_64架构下实践2.5中的内容,提交代码和实践截图
  2. 把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与汇编的混合编程的更多相关文章

  1. ARM中C和汇编混合编程及示例(转)

    在嵌入式系统开发中,目前使用的主要编程语言是C和汇编,C++已经有相应的编译器,但是现在使用还是比较少的.在稍大规模的嵌入式软件中,例如含有OS,大部分的代码都是用C编写的,主要是因为C语言的结构比较 ...

  2. ARM汇编与C混合编程

    GNU内联汇编 内联汇编即在C中直接使用汇编语句进行编程,使程序可以在C程序中实现C语言不能完成的一些工作,例如,在下面几种情况中必须使用内联汇编或嵌入型汇编 程序中使用饱和算术运算(Saturati ...

  3. Android程序中,内嵌ELF可执行文件-- Android开发C语言混合编程总结

    前言 都知道的,Android基于Linux系统,然后覆盖了一层由Java虚拟机为核心的壳系统.跟一般常见的Linux+Java系统不同的,是其中有对硬件驱动进行支持,以避开GPL开源协议限制的HAL ...

  4. Cortex-M3中C与汇编的交互

          以下内容摘自<ARM Cortex-M3权威指南>         概览       在CM3 上编程,既可以使用C 也可以使用汇编.可能还有其它语言的编译器,但是大多数人还是 ...

  5. 理解ATL中的一些汇编代码(通过Thunk技术来调用类成员函数)

    我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以 ...

  6. KEIL C51程序中如何嵌入汇编

    模块内接口:使用如下标志符:#pragma asm汇编语句#pragma endasm注意:如果在c51程序中使用了汇编语言,注意在Keil编译器中需要激活Properties中的“Generate ...

  7. Linux C中内联汇编的语法格式及使用方法(Inline Assembly in Linux C)【转】

    转自:http://www.linuxidc.com/Linux/2013-06/85221p3.htm 阅读Linux内核源码或对代码做性能优化时,经常会有在C语言中嵌入一段汇编代码的需求,这种嵌入 ...

  8. x64汇编第四讲,c / C++中调用x64汇编

    目录 x64汇编第四讲,c / C++中调用x64汇编 一丶简介 1.说明 二丶C/C++调用 asm64.asm函数. 1.配置asm参与生成 2.给Asm文件添加函数代码 3.C/C++调用asm ...

  9. C51与汇编混合编程详解

    C51和汇编混合编程(1)-C语言中嵌入汇编 1.在 C文件中要嵌入汇编代码片以如下方式加入汇编代码: #pragma ASM ;Assembler Code Here #pragma ENDASM ...

  10. c语言环境初始化&c语言和汇编混合编程

    bootloader通常会分为两个阶段:第一阶段采用汇编语言来编写,主要是一些核心的初始化工作(内存,时钟的初始化),第二阶段使用C语言来编写,主要是它会完成一些板载硬件的初始化(串口,网口)然后其启 ...

随机推荐

  1. 计算机网络14 Internet网络层主要功能 IP协议 路由协议 ICMP协议

    1 主机.路由器网络层主要功能 2 IP数据报 2.1 图示 2.2 字段详细介绍 1)版本号 占4位:IP协议的版本号.4表示IPv4,6表示IPv6. 2)首部长度 占4位:表示IP分组首部长度. ...

  2. webrtc QOS笔记一 Neteq直方图算法浅读

    webrtc QOS笔记一 Neteq直方图算法浅读 目录 webrtc QOS笔记一 Neteq直方图算法浅读 Histogram Algorithm 获取目标延迟 遗忘因子曲线 想起博客园帐号了, ...

  3. IP转换

    IP转换 目录 IP转换 1 127.1 ? 2 IPv4两段点分十进制表示 3 IPv4一段十进制表示 4 IPv4地址有效地变换形式 5 IP地址进制转换网站 6 参考博客 1 127.1 ? 首 ...

  4. select去除默认样式

    select { /*Chrome同Firefox与IE里面的右侧三角显示的样式不同*/ border: solid 1px #ddd; /*将默认的select选择框样式清除*/ appearanc ...

  5. 通过反射机制简化 JDBC ResultSet 实体类的注入

    提出问题 查询完某个表之后,一般都是把结果的每一个字段注入到一个实体类中.比如,数据库 users 表,查询出来的结果注入到 User 实体类中. 通过 while 遍历 ResultSet,把字段对 ...

  6. 08. AssetBundle.LoadFromFile

    参数 path 文件在磁盘上的路径. crc 未压缩内容的 CRC-32 校验和(可选).如果该参数不为零,则加载前将内容与校验和进行比较,如果不匹配则给出错误. offset 字节偏移(可选).该值 ...

  7. Mybatis-Plus 之BaseMapper 方法详解

    package com.itheima.dao; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomido ...

  8. 第十一周作业-N67044-张铭扬

    1. redis主从复制原理? 1 从节点1.2 2 127.0.0.1:6379> replicaof 10.0.0.157 6379 3 OK 4 127.0.0.1:6379> co ...

  9. ConvFormer: Closing the Gap Between CNN and Vision Transformers概述

    0.前言 相关资料: arxiv github 论文解读 论文基本信息: 发表时间:arxiv2022(2022.9.16) 1.针对的问题 CNN虽然效率更高,能够建模局部关系,易于训练,收敛速度快 ...

  10. Linux常用的性能分析

    参考文档:https://www.runoob.com/w3cnote/linux-common-command-2.html 一.ps -aux ps -aux ps -ef -a:所有进程. -u ...