zoukankan      html  css  js  c++  java
  • 树莓派汇编语言程序设计入门实验

    实验3-2 查找最大数

    编写汇编代码

    参考指导书,编写实现查找最大数功能的汇编代码,将我学号后四位1218作为最大数

    .section .data
    .align 3
    my_data:
    	.quad 1
    	.quad 2
    	.quad 5
    	.quad 1218
    	.quad 10
    	.quad 12
    
    my_data_count:
    	.quad 6
    
    .align 3 
    print_data:
    	.string "big data: %d
    "
    
    .section .text
    .globl main
    main:
    	stp x29, x30, [sp, -16]!
    
    	ldr x0, =my_data
    	ldr x1, my_data_count
    
    	add x4, x0, #40
    
    	mov x3, xzr
    1:
    	ldr x2, [x0], #8
    	cmp x2, x3
    	csel x3, x2, x3, hi
    
    	cmp x0, x4
    	b.ls 1b
    
    	ldr x0, =print_data
    	mov x1, x3
    
    	bl printf
    
    	ldp x29, x30, [sp], 16
    	ret
    
    

    编译运行

    汇编代码
    上学期我们在计算机组成原理课上曾学习过MIPS架构,再结合这学期在ARM架构的树莓派上实践,总结MIPS和ARM有如下区别:

    • MIPS指令很简单,格式很规整,就可以做很快(频率很高)。这符合RISC的初衷,但是功耗可能会比较大些(和频率有关),然后编译生成的代码很长(你不得不用大一点的Cache )。
    • ARM指令很复杂,而且电路实现起来会比精简的指令相对复杂,当面积和功耗优先级高时,最高运行频率可能不会太高。

    下面使用gcc maxnum.s -o maxnum -g --static进行编译,运行结果如下

    成功找出最大数

    使用gdb单步调试汇编程序

    发现OpenEuler操作系统并没有安装gdb,于是sudo yum install gdb

    使用gdb --tui ./maxnum来进行调试。

    使用b main在主函数设置断点

    使用run

    使用ns单步执行

    使用info reg xn查看寄存器的值

    实验3-3 通过C语言调用汇编函数

    编辑两个代码文件:
    第一个是arm汇编代码文件compare.s:

    .section .text
    .globl compare_data
    compare_data:
            cmp x0, x1
            csel x0, x0, x1, hi
            ret
    

    第二个是包含主函数的C代码文件:main.c:

    #include <stdio.h>
    
    extern int compare_data(int a, int b);
    
    int main()
    {
            int val;
    
            val = compare_data(1218,1111);
    
            printf("bigger data is:%d
    ",val);
    }
    

    使用gcc compare.s main.c -o compare编译

    实验3-4 通过汇编语言调用C函数

    和实验3-3类似,相当于反过来,比较函数用C写的,主函数用汇编写
    compare.c:

    int compare_data(int a, int b)
    {
            return (a >= b) ? a : b;
    }
    

    main.s

    .section .data
    .align 3
    
    print_data:
            .string "bigger data is:%d
    "
    
    .section .text
    .globl main
    main:
            stp     x29, x30, [sp, -16]!
    
            mov x0, #6
            mov x1, #5
            bl compare_data
    
            mov x1, x0
            ldr x0, =print_data
    
            mov x1, x0
            ldr x0, =print_data
            bl printf
    
            ldp x29, x30, [sp], 16
            ret
    

    运行结果如下

    实验3-5 gcc内联汇编

    内联汇编编译即在C代码中嵌入汇编代码
    测试代码test.c如下:

    #include <stdio.h>
    
    static int compare_data(int a, int b)
    {
            int val;
    
            asm volatile(
                            "cmp %1, %2
    "
                            "csel %0, %1, %2, hi
    "
                            : "+r" (val)
                            : "r" (a), "r"(b)
                            : "memory");
    
            return val;
    }
    
    int main()
    {
            int val;
    
            val = compare_data(5,6);
            printf("big data: %d
    ", val);
    
            val = compare_data(1111,1218);
            printf("big data: %d
    ", val);
    }
    

    运行结果

  • 相关阅读:
    SpringCloud学习教程
    Google浏览器插件推荐
    谷歌身份验证器使用
    js控制某个div在页面加载完成5秒后隐藏
    通过城市联动实时将地址显示到text中
    百度地图通过地址查询并且定位
    yii2.0验证码的两种实现方式
    yii2.0 中数据查询中 or、in、between 及session的使用
    Calling unknown method: appmodulesmobilecontrollersCompanyController::redirect()
    页面权限跳转
  • 原文地址:https://www.cnblogs.com/20191218tangqiheng/p/15496544.html
Copyright © 2011-2022 走看看