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

  1. #include <stdio.h>
  2. extern int B();
  3. int A(int x, int y){
  4. int d, e, f;
  5. d = 4;
  6. e = 5;
  7. f = 6;
  8. f = B(d,e);
  9. }

a.s file

  1. A:
  2. pushl %ebp
  3. movl %esp, %ebp
  4. subl $24, %esp
  5. movl $4, -20(%ebp)
  6. movl $5, -16(%ebp)
  7. movl $6, -12(%ebp)
  8. subl $8, %esp
  9. pushl -16(%ebp)
  10. pushl -20(%ebp)
  11. call B
  12. addl $16, %esp
  13. movl %eax, -12(%ebp)
  14. nop
  15. leave
  16. ret

2.5.2用汇编语言实现函数

示例2.2

获取CPU寄存器

s.s file

  1. .global get_esp, get_ebp
  2. get_esp:
  3. movl %esp, %eax
  4. ret
  5. get_ebp:
  6. movl %ebp, %eax
  7. ret

print.c

  1. #include <stdio.h>
  2. int main(){
  3. int ebp, esp;
  4. ebp = get_ebp();
  5. esp = get_esp();
  6. printf("ebp=%8x esp=%8x\n", ebp, esp);
  7. }

编译运行截图

示例2.3

用汇编语言编写mysum函数

mysum.s

  1. .code32
  2. .text
  3. .global mysum, printf
  4. mysum:
  5. pushl %ebp
  6. movl %esp, %ebp
  7. movl 8(%ebp), %eax
  8. addl 12(%ebp), %eax
  9. movl %ebp, %esp
  10. pop %ebp
  11. ret

sum.c

  1. #include <stdio.h>
  2. int main(){
  3. int a, b, c;
  4. a = 123;
  5. b = 456;
  6. c = mysum(a, b);
  7. printf("c=%d\n",c);
  8. }

编译运行截图

2.5.3从汇编中调用C函数

示例2.4:访问全局变量并调用printf()

sub.s

  1. .text
  2. .global sub, a, d, printf
  3. sub:
  4. pushl %ebp
  5. movl %esp, %ebp
  6. pushl b
  7. pushl a
  8. pushl $fmt
  9. call printf
  10. addl $12, %esp
  11. leave
  12. ret
  13. .data
  14. fmt: .asciz "a=%d b=%d\n"

submain.c

  1. #include <stdio.h>
  2. int a, b;
  3. int main(){
  4. a = 100;
  5. b = 200;
  6. sub();
  7. }

编译运行截图

任务二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

  1. #include <stdio.h>
  2. extern int B();
  3. int A(int x, int y){
  4. int d, e, f;
  5. d = 4;
  6. e = 5;
  7. f = 6;
  8. f = B(d,e);
  9. }

a.s file

  1. A:
  2. pushq %rbp
  3. movq %rsp, %rbp
  4. subq $32, %rsp
  5. movl %edi, -20(%rbp)
  6. movl %esi, -24(%rbp)
  7. movl $4, -4(%rbp)
  8. movl $5, -8(%rbp)
  9. movl $6, -12(%rbp)
  10. movl -8(%rbp), %edx
  11. movl -4(%rbp), %eax
  12. movl %edx, %esi
  13. movl %eax, %edi
  14. movl $0, %eax
  15. call B
  16. movl %eax, -12(%rbp)
  17. leave
  18. ret

2.5.2用汇编语言实现函数

示例2.2

获取CPU寄存器

s.s file

  1. .globl get_esp, get_ebp
  2. get_esp:
  3. movq %rsp, %rax
  4. ret
  5. get_ebp:
  6. movq %rsp, %rax
  7. ret

print.c

  1. #include <stdio.h>
  2. int main(){
  3. int ebp, esp;
  4. ebp = get_ebp();
  5. esp = get_esp();
  6. printf("rbp=%8x rsp=%8x\n", ebp, esp);
  7. }

编译运行截图

示例2.3

用汇编语言编写mysum函数

mysum.s

  1. .text
  2. .global mysum, printf
  3. mysum:
  4. pushq %rbp
  5. movq %rsp, %rbp
  6. movl %edi, -4(%rbp)
  7. movl %esi, -8(%rbp)
  8. movl -8(%rbp), %eax
  9. addl -4(%rbp), %eax
  10. popq %rbp
  11. ret

sum.c

  1. #include <stdio.h>
  2. int main(){
  3. int a, b, c;
  4. a = 123;
  5. b = 456;
  6. c = mysum(a, b);
  7. printf("c=%d\n",c);
  8. }

编译运行截图

2.5.3从汇编中调用C函数

示例2.4:访问全局变量并调用printf()

sub.s

  1. .text
  2. .global sub, a, d, printf
  3. sub:
  4. pushq %rbp
  5. movq %rsp, %rbp
  6. movl b, %edx
  7. movl a, %esi
  8. movl $fmt, %edi
  9. call printf
  10. leave
  11. ret
  12. .data
  13. fmt: .asciz "a=%d b=%d\n"

submain.c

  1. #include <stdio.h>
  2. int a, b;
  3. int main(){
  4. a = 100;
  5. b = 200;
  6. sub();
  7. }

编译运行截图

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. 重学SpringBoot. step4 Redis的应用

    Redis的应用 Redis支持的七种数据类型:字符串.散列.列表(链表).集合.有序集合.基数和地理位置,具体用Java怎么操作其实可以直接看redisTemplate的源代码. Redis引出来的 ...

  2. log4j 完美版配置

    百度的LOG4J配置记录一下 目前无时间阅读,反正能用就行了 # priority :debug<info<warn<error #you cannot specify every ...

  3. Listen 1音乐播放器

    Listen 1 Listen 1可以搜索和播放来自网易云音乐,QQ音乐,酷狗音乐,酷我音乐,Bilibili,咪咕音乐网站的歌曲,让你的曲库更全面.还支持歌单功能,你可以方便的播放,收藏和创建自己的 ...

  4. 亲测有效 Hyper V3.4.0 终端美化工具 支持win/mac

    亲测有效 Hyper V3.4.0 终端美化工具 支持win/mac Hyper 是一款终端美化工具 基于Web技术,JS/HTML/CSS ,支持扩展增强,很不错! 且支持win,mac 下载地址 ...

  5. C# 高德地图WebApi对接示例

    1.登录或注册高德地图开放平台然后申请应用key(需要认证个人或企业开发者) 高德开放平台 | 高德地图API (amap.com)https://developer.amap.com/?ref=ht ...

  6. element-UI el-table动态显示隐藏列造成固定一侧的列(fixed=“left/right“)错误显示

    问题原因:多个tabs共用一个实体,动态显示隐藏列 出现了固定在右侧的列(fixed="right")错位 [解决方案] 表格的重新布局,只要table数据发生变化的时候就重新渲染 ...

  7. Sentinel熔断与限流

    1.简介 在线文档: https://sentinelguard.io/zh-cn/docs/system-adaptive-protection.html 功能: 流量控制 速率控制 熔断和限流 和 ...

  8. STM32F4寄存器初始化:编码器

    RCC->APB1ENR|=1<<0; //TIM2时钟使能 RCC->APB1ENR|=1<<1; //TIM3时钟使能 RCC->APB1ENR|=1&l ...

  9. 使用一个文件集中管理你的 Nuget 依赖版本号

    在 .net 7 以前,项目对于 nuget 依赖项的版本依赖散落与解决方案的各个角落.这导致升级维护和查看的时候都比较麻烦.在 .net 7 中,你可以使用一个文件来集中管理你的 Nuget 依赖版 ...

  10. Git远程提交的冲突解决

    先本地直接提交代码:git push origin master 如果别人在自己之前提交了修改,git会提示push失败,需要先pull远程代码:git pull origin/master (拉取远 ...