汇编(实现C语言程序的调用)

news2024/9/20 2:08:42

一、ARM汇编指令

  1. mov: 将一个值或寄存器的内容移动到另一个寄存器中。这个指令可以用来赋值。

    示例:mov r0, #5 // 将立即数 5 移动到寄存器 r0

  2. add: 执行加法操作,将两个操作数相加,并将结果存储在目标寄存器中。

    示例:add r0, r1, r2 // 将 r1 和 r2 的值相加,并将结果存储在 r0 中

  3. sub: 执行减法操作,从一个寄存器的值中减去另一个寄存器的值,并将结果存储在目标寄存器中。

    示例:sub r0, r1, r2 // 计算 r1 - r2 的值,并将结果存储在 r0 中

  4. ldr: 从内存中加载数据到寄存器中。

    示例:ldr r0, [r1] // 从 r1 指向的地址加载数据到 r0 中

  5. bic: 对两个操作数执行按位清除运算,保留第一个操作数中的位,而将第二个操作数中的位清零。

    示例:bic r0, r1, r2 // 清除 r1 中与 r2 中相同的位,将结果存储在 r0 中

  6. orr: 对两个操作数执行按位或运算。

    示例:orr r0, r1, r2 // 将 r1 和 r2 的位进行按位或运算,结果存储在 r0 中

  7. cmp: 比较两个寄存器中的值,设置相应的标志位(如零标志、负标志等),但不存储结果。

    示例:cmp r0, r1 // 比较 r0 和 r1 的值

  8. stmfd: 将多个寄存器的内容存入内存,按全降序存储,通常用于保存寄存器状态。

    示例:stmfd sp!, {r0, r1, r2} // 将 r0, r1, r2 存储到栈中

  9. ldmfd: 从内存中加载多个寄存器的内容,按全升序恢复寄存器状态。

    示例:ldmfd sp!, {r0, r1, r2} // 从栈中加载 r0, r1, r2 的值

二、跳转语句

  1. b: 无条件跳转指令,跳转到指定的标签或地址。这是ARM汇编中最常用的跳转指令。

    示例:b label // 跳转到名为 label 的位置

  2. bl: 带链接的跳转,除了跳转到指定地址外,还将返回地址(下一条指令的地址)保存到链接寄存器(LR 或 r14)中。常用于子程序调用。

    示例:bl function // 跳转到 function,并将返回地址存储在 LR 中

  3. bx: 通过指定的寄存器地址跳转,并且可以根据寄存器的最低位设置处理器的状态(如进入 ARM 或 Thumb 状态)。它通常用于从子程序返回。

    示例:bx r0 // 跳转到 r0 寄存器中存储的地址

栈指针寄存器

  • SP(栈指针寄存器): SP 寄存器用于指向当前栈的顶部。栈通常用于存储局部变量、保存返回地址等。当使用 stmfd 和 ldmfd 指令时,stack pointer (SP) 寄存器可用于管理函数调用和返回。

CPSR 寄存器相关指令

  1. mrs: 从 CPSR(当前程序状态寄存器)读取数据。当需要获取当前状态或标志位时,使用此指令。

    示例:mrs r0, cpsr // 将 CPSR 的值加载到 r0 中

  2. msr: 设置 CPSR 的某些位。这可以用于改变处理器的状态或控制特权级别。

    示例:msr cpsr_c, r0 // 将 r0 的内容写入 CPSR 中的控制位

三、汇编

preserve8               ; 保留8字节对齐  
area reset, code, readonly ; 定义一个名为“reset”的只读代码区域  
code32                  ; 设定代码为32位  
entry                   ; 定义入口点  

b start                 ; 跳转到 start 标签,开始程序执行  
ldr pc, =do_undifined   ; 将 do_undifined 的地址加载到程序计数器(PC),设置未定义指令处理  
ldr pc, =do_swi        ; 将 do_swi 的地址加载到 PC,设置软件中断处理  
ldr pc, =do_p_abort    ; 将 do_p_abort 的地址加载到 PC,设置预取中止处理  
ldr pc, =do_d_abort    ; 将 do_d_abort 的地址加载到 PC,设置数据中止处理  
nop                     ; 空操作,通常用于填充或延迟  
ldr pc, =do_irq        ; 将 do_irq 的地址加载到 PC,设置外部中断处理  
ldr pc, =do_fiq        ; 将 do_fiq 的地址加载到 PC,设置快速中断处理  

do_fiq                  ; 快速中断处理程序  
	b do_fiq              ; 无限循环,等待快速中断  

do_irq                  ; 外部中断处理程序  
	import irq_handler    ; 导入 irq_handler 函数  
	sub lr, lr, #4        ; 将链接寄存器(LR)减去4,以调整返回地址  
	stmfd sp!, {r0-r12, lr} ; 将 r0-r12 和 LR 保存到栈中,进行现场保护  
	bl irq_handler        ; 调用中断处理程序  
	ldmfd sp!, {r0-r12, pc}^ ; 恢复寄存器并返回  

do_d_abort              ; 数据中止处理程序  
	b do_d_abort          ; 无限循环,等待数据中止  

do_p_abort              ; 预取中止处理程序  
	b do_p_abort          ; 无限循环,等待预取中止  

do_swi                  ; 软件中断处理程序  
	import swi_handler     ; 导入 swi_handler 函数  
	stmfd sp!, {r0-r12, lr} ; 保存 r0-r12 和 LR 到栈中  
	bl swi_handler        ;  调用软件中断处理程序  
	ldmfd sp!, {r0-r12, pc}^ ; 恢复寄存器并返回  

do_undifined            ; 未定义指令处理程序  
	b do_undifined        ; 无限循环,等待未定义指令  

start                   ; 程序启动点  
	ldr sp, =0x40001000  ; 将栈指针(SP)初始化为指定地址  

	mrs r0, cpsr          ; 读取当前程序状态寄存器(CPSR)  
	bic r0, r0, #0x1F     ; 清除 CPSR 中的模式位  
	orr r0, r0, #0x12    ; 设置 CPSR 进入 SVC 模式  
	bic r0, #(1 << 7)     ; 清除 CPSR 中的 F 标志位  
	msr cpsr_c, r0       ; 更新 CPSR  

	ldr r0, =0x40001000  ; 将地址 0x40001000 加载到 r0   
	sub r0, r0, #1024    ; 计算栈顶地址  
	mov sp, r0           ; 设置栈指针 SP  

	mrs r0, cpsr          ; 读取当前 CPSR  
	bic r0, r0, #0x1F     ; 清除模式位  
	orr r0, r0, #0x10    ; 设置 CPSR 进入 IRQ 模式  
	msr cpsr_c, r0       ; 更新 CPSR  

	ldr r0, =0x40001000  ; 将地址 0x40001000 加载到 r0  
	sub r0, r0, #2048    ; 计算新的栈顶地址  
	mov sp, r0           ; 设置栈指针 SP  

	import main           ; 导入 main 函数  
	b main               ; 跳转到 main 函数  

asm_fn                  ; 汇编函数的标签  
	export asm_fn         ; 导出 asm_fn 函数  
	swi #7                ; 触发软件中断,调用系统服务  
	bx lr                 ; 返回到调用者  

finished                ; 完成标签  
	b finished            ; 无限循环,等待程序结束  

	end                    ; 汇编代码的结束标志

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2147595.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

硬件工程师笔试面试——保险丝

目录 10、保险丝 10.1 基础 保险丝原理图 保险丝实物图 10.1.1 概念 10.1.2 保险丝的工作原理 10.1.3 保险丝的主要类型 10.1.4 保险丝的选择和使用注意事项 10.2 相关问题 10.2.1 保险丝的额定电流和额定电压是如何确定的? 10.2.2 保险丝的熔断速度对电路保护有何…

二进制补码及与原码的互相转换方法-成都仪器定制

大沙把一些基础的知识说清楚&#xff0c;本文介绍二进制补码及与原码的转换方法。 先说原码&#xff0c;原码‌是一种计算机中对数字的二进制定点表示方法。在原码表示法中&#xff0c;数值前面增加了一位符号位&#xff0c;最高位为符号位&#xff0c;0表示正数&#xff0c;1表…

keil调试变量值被篡改问题

今天遇到一个代码中变量值被篡改的问题&#xff0c;某个数组的第一个值运行一段时间之后变成了0&#xff0c;如图&#xff1a; 看现象基本可以断定是内存越界导致的&#xff0c;但是要如果定位是哪里内存越界呢? keil提供了两个工具 1、set access breakpoint at(设置访问断点…

项目小总结

这段时间主要把大概的开发流程了解完毕 修改了&#xff0c;并画了几个界面 一.界面 修改为 博客主页 个人中心 二.前后端分离开发 写前端时 就可以假设拿到这些数据了 const blogData2 {blog:{id:1,title: "如何编程飞人",author_id: 1,content: "这是一篇…

数据结构之二叉树遍历

二叉树的遍历 先序遍历 先输入父节点&#xff0c;再遍历左子树和右子树&#xff1a;A、B、D、E、C、F、G 中序遍历 先遍历左子树&#xff0c;再输出父节点&#xff0c;再遍历右子树&#xff1a;D、B、E、A、F、C、G 后序遍历 先遍历左子树&#xff0c;再遍历右子树&#xff0c;…

爬虫框架之Scrapy介绍——高效方便

# 近年来大数据分析、数据可视化和python等课程逐渐在大学各个学科中铺展开来&#xff0c;这样一来爬虫在平时小作业和期中、期末报告中出现的频率也逐渐变高。那么单一的使用requests库&#xff0c;自己从头到尾的的设计&#xff0c;考虑数据提取、线程管理和数据存储等方方面…

微服务架构详解

微服务与SOA概述 SOA历史 SOA示例 微服务历史 SOA 被抛弃了么? 微服务与 SOA 剖析 SOA 架构剖析 ESB就是一个一个微服务的功能 ESB 功能举例 对象转换还有逻辑转换 很多东西都要在ESB里面处理 微服务剖析 把一个单体结构拆分多个小服务。为了让小服务之间通信方便&#x…

用AI的智慧,传递感恩之心——GPT-4o助力教师节祝福

随着科技的飞速发展&#xff0c;人工智能在我们生活中的应用日益广泛。在这个教师节&#xff0c;不仅可以用传统的方式表达对老师的感恩之情&#xff0c;还可以借助OpenAI最新推出的GPT-4o模型&#xff0c;生成独特而温暖的祝福语和精美海报&#xff0c;让我们的感恩显得更加与…

Renesas R7FA8D1BH (Cortex®-M85)的UART使用介绍

目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 FSP配置UART 2.1 配置参数 2.2 UART模块介绍 3 接口函数介绍 3.1 R_SCI_B_UART_Open() 3.2 R_SCI_B_UART_Close() 3.3 R_SCI_B_UART_Read() 3.4 R_SCI_B_UART_Write() 3.5 R_SCI_B_UAR…

【iOS】——JSONModel源码

JSONModel用法 基本用法 将传入的字典转换成模型&#xff1a; 首先定义模型类&#xff1a; interface Person : JSONModel property (nonatomic, copy) NSString *name; property (nonatomic, copy) NSString *sex; property (nonatomic, assign) NSInteger age; end接…

Java 23 的12 个新特性!!

Java 23 来啦&#xff01;和 Java 22 一样&#xff0c;这也是一个非 LTS&#xff08;长期支持&#xff09;版本&#xff0c;Oracle 仅提供六个月的支持。下一个长期支持版是 Java 25&#xff0c;预计明年 9 月份发布。 Java 23 一共有 12 个新特性&#xff01; 有同学表示&…

Qwen 2.5:阿里巴巴集团的新一代大型语言模型

Qwen 2.5&#xff1a;阿里巴巴集团的新一代大型语言模型 摘要&#xff1a; 在人工智能领域&#xff0c;大型语言模型&#xff08;LLMs&#xff09;的发展日新月异&#xff0c;它们在自然语言处理&#xff08;NLP&#xff09;和多模态任务中扮演着越来越重要的角色。阿里巴巴集…

「数据科学」清洗数据,使用Python语言处理数据集中的重复值

数据集中的重复值&#xff0c;产生的原因有很多&#xff0c;如果不进行处理的话&#xff0c;会对我们的后续分析过程&#xff0c;产生很大的影响。比如说&#xff0c;在统计汇总数据的时候&#xff0c;重复数据就会导致数据总数增多。要是重复数据多的话&#xff0c;会影响我们…

2024 go-zero社交项目实战

背景 一位商业大亨&#xff0c;他非常看好国内的社交产品赛道&#xff0c;想要造一款属于的社交产品&#xff0c;于是他找到了负责软件研发的小明。 小明跟张三一拍即合&#xff0c;小明决定跟张三大干一番。 社交产品MVP版本需求 MVP指&#xff1a;Minimum Viable Product&…

Java自定义集合-基于文件的泛型列表 LocalFileArrayList

Java实现基于文件的泛型列表 LocalFileArrayList 简介核心概念泛型文件操作实现细节构造函数读取和写入文件类型转换List 接口方法实现总结调用示例完整代码简介 LocalFileArrayList我自己随便起的,没怎么思考,不一定是最适合的名字。搞这东西主要是有些需求用到的数据量太大…

95分App引领年轻人省钱赚钱新风尚,闲置也能变宝藏

随着时代的发展&#xff0c;年轻一代的消费观念正经历着深刻的变革。他们不再盲目追求新品、奢侈品&#xff0c;而是喜欢上购买闲置物品来满足日常所需。在消费的同时&#xff0c;加入了卖家的行列。对自己拥有的闲置物品开启“断舍离”&#xff0c;纷纷在闲置平台进行售卖。这…

鸿蒙媒体开发系列05——音频并发播放管理与音量管理

如果你也对鸿蒙开发感兴趣&#xff0c;加入“Harmony自习室”吧&#xff01;扫描下方名片&#xff0c;关注公众号&#xff0c;公众号更新更快&#xff0c;同时也有更多学习资料和技术讨论群。 1、多音频播放的并发管理 多音频并发&#xff0c;即多个音频流同时播放。此场景下&…

GAMES104:15 游戏引擎的玩法系统基础-学习笔记

文章目录 0&#xff0c;游戏性课程框架一&#xff0c;事件机制1.1 事件的定义1.2 callback的注册1.3 事件的分发系统 二&#xff0c;游戏逻辑与脚本系统2.1 特点和常见脚本语言2.2 脚本语言的GO管理2.3 脚本语言的架构2.4 可视化脚本 三&#xff0c;Gameplay 开发中的3C &#…

关雅荻发文批评某脱口秀节目审核问题:为博流量乱搞事情?

最近&#xff0c;针对某脱口秀节目中引发的网络舆情&#xff0c;电影制片人关雅荻发文严厉批评该视频平台的审核问题&#xff0c;指出“这家视频网站对应的节目审核环节严重失职&#xff0c;或者有意渎职&#xff0c;这个脱口秀节目制作方在自己内容策划和制作也有明显失职、严…

一招有效清理宠物浮毛,养宠搭子——质量好的宠物空气净化器推荐

害&#xff0c;好不容易毕业找到了工作进入社会&#xff0c;我以为可以自己决定事情了&#xff0c;结果上周又被我妈臭骂一通。因为我瞒着他们养猫了&#xff0c;他们来看我的时候才知道&#xff0c;说我刚出来养活自己都够呛&#xff0c;哪里还能照顾猫。在我好说歹说下&#…