,学习和使用门槛较高 接下来我们要学习的就是GNU计划众多的产物之一GNU FOR ARM 汇编器与指令集 什么是汇编器 将汇编语言翻译成机器码的工具 什么是编译器 将高级语言翻译成机器语言或者汇编语言的工具 汇编器和编译器的区别 汇编器的服务对象是汇编语言,编译器的服务对象是高级语言 汇编器和汇编语法伪指令的关系 不同的CPU对应不同的指令集 ,不同的汇编器对应不同的伪指令集和汇编语法。 每种汇编器都可以有自己的伪指令集和自己的语法 使用不同的汇编器汇编同一个cpu架构的汇编代码,所对应的指令绝对是一致的,但伪指令各有千秋 ;使用ARM官方的汇编器 AREA test, CODE 例子:ARM原生编译器和GNU FOR ARM 两种汇编器语法对比一览表 GNU ARM汇编 ADS ARM汇编 “@”或“/…/” “;” .include GET .equ EQU .global C语言调汇编函数 第一步,在汇编原文件中将函数暴露出来给供外部调用,使用export或者global伪指令: AREA code, CODE export arm_strcpy ;或者使用global
ARM汇编语言指令集汇总 跳转指令 存储器和寄存器交互数据指令(内存访问) 数据传送指令 数据算术运算指令 数据逻辑运算指令 比较指令 组合和分离指令 并行指令 测试指令 ThumbEE指令 协处理器指令 加 ️ SUB 减️ MUL 乘 DIV 除 ADC 带进位的加法指令 SBC 带借位减法指令 AND 逻辑“与” ASR 算术右移 RSB 反向减法 SBC 带进位减法 RSC 带进位反向减法(仅 ARM 可用于所有 ARM 体系结构 无线 MMX 技术伪指令 指令 简介 例子 TMCR 将源寄存器 Rn 的内容移到控制寄存器 wCn 中 TMCR wc1, r10 TMCRR 将两个源寄存器 RnLo R0,R1,LSL #2 R0=R1*4 寄存器间接寻址 LDR R0,[R1] ;将R1寄存器中的值作为地址,取出值给R0 寄存器间接寻址偏移寻址 LDR R0,[R1,#-4] 更多可参考 《ARM 汇编指南》
代金券、腾讯视频VIP、QQ音乐VIP、QB、公仔等奖励等你来拿!
机器语言 直接对硬件操作的语言,由多个0、1构成的。是低级语言底层。 汇编语言 汇编语言同机器语言一样直接对硬件操作。 汇编语言虽麻烦,但是所能完成的操作不是一般高级语言能够实现的。 且生成的可执行文件小,执行速度快 高级语言 高级语言所编制的程序不能直接被计算机识别,必须经过转换才能执行。 但如果要修改代码,必须再重新全篇编译生成可执行文件,修改不方便。 编译后程序运行时不需要再次重新编译,直接执行可执行文件即可。 程序执行效率高、依赖编译器、跨平台性差 解释类(Python、Java、PHP、Ruby等语言) 程序源码边编译边执行,逐行编译,不能生成可独立执行的文件。 但是这种方式可以灵活调整更改。 总结: 机器语言 优点是最底层,速度最快,缺点是最复杂,开发效率最低 汇编语言 优点是比较底层,速度最快,缺点是复杂,开发效率最低 高级语言 编译型语言执行速度快,不依赖语言环境运行
MIPS汇编中的分段处理.data #数据段 .text #代码段传送指令加载立即数指令 lili(load immediate) :用于将立即数传送给寄存器li $t0,1 ;十六进制数据使用0x前缀表示加载地址指令 将字符串数据所在的地址赋值给$a0寄存器寄存器数据传送指令move用于将一个寄存器中的数据传送至另一个寄存器当中move $t0,$t1 # 将寄存器$t1中的数据传送至$t0系统服务指令 syscall在C语言中输出文本可以使用 printf函数,但是汇编中没有printf这么一说,如果想要输出文本,需要借助syscall指令如果想要输出一个数字1,那么syscall指令从$a0寄存器中取出需要输出的数据因此, 你在执行syscall string to display after the first stringNA使用syscall指令输出helloworld示例:.data msg: .ascii hello world0 #类似于C语言中 li $v0,10 syscallsub: li $v0,4 la $a0,msg_yes syscall练习2: 将以下c代码转换成mips汇编代码:求累加之和1+2+3+.....+100 int
或者Flase,可是在汇编语言里面没有这么简便,那它又是如何对两个数据之间大小进行判断的呢? WHILE Counter < 10 程序段 WEND 汇编语言和C语言交互 内嵌汇编 外链汇编 1.引入其他源文件函数 使用import或者extern伪指令 ;使用import伪指令 AREA code C语言调汇编函数 第一步,在汇编原文件中将函数暴露出来给供外部调用,使用export或者global伪指令: AREA code, CODE export arm_strcpy ;或者使用global c语言函数 第一步,在C文件中编写好函数 int c_sum(int a,int b){ return a+b; } 第二步, 在汇编文件中引入函数,使用import或者extern伪指令 AREA arm_strcpy arm_strcpy mov R0,#1 ;第一个参数 mov R1,#2 ;第二个参数 BL c_sum ;结果存放至R0中 END 5.内嵌汇编 在C语言中嵌入汇编代码
arm代码示例 .text ;代码段 .global _A,_B ;定义两个全局函数 A和B _A: mov x0 ,#0xa0 ;arm汇编中数据用#开头 mov x1 ,#0x00 add 汇编中数据用#开头 str x30,[sp,#-0x10]! 寄存器进行临时保护, 这两个寄存器占用16个字节, 加上sum函数的局部变量和参数所占的16个字节,一共是32个字节 叶子函数 函数体中没有调用其他函数的函数称之为叶子函数,又称为末尾函数 这种函数在编写汇编代码时可以省略使用栈空间 article/details/102762635 orr w8,wzr,#0x1 ;将立即数0x1和0进行或运算, 然后复制给w8 函数嵌套复用 假如有两个函数A和B,它们的调用链为:A–>B–>A 在高级语言中 ,A函数进行了复用,但是在汇编当中并没有复用的概念,每调用一个函数便开辟一次栈空间, 因此哪怕是调用同一个函数,如果递归嵌套次数过多,就会造成内存溢出 状态寄存器(标记寄存器) cpsr(current
在dos下输入汇编源程序的方法 一 环境的搭建 windows下运行“windows+r”键入“cmd”,就就进入dos系统,输入“debug”进入debug程序(windows7下之间按照上述步骤输入即可 -a指令 用法:-a [内存地址] 作用:从指定地址开始逐条输入汇编语句并汇编成机器码存入内存中,若地址缺省,则在上一条指令的最后一条指令之后输入汇编语句。 3 -u指令 用法:-u [起始地址[终止地址]] 作用:从起始地址到终止地址反汇编目标代码。 若缺省地址,则默认从CS:0100地址开始,例如: -u 显示器上显示出程序的内存地址,指令机器码的汇编源程序三列对照清单。 4. 6 -g指令 用法:-g[起始地址] 作用:控制程序有当前IP处运行,直至程序结束 三 汇编源程序的输入 ······························· 遇到问题了,
汇编与机器指令是一一对应的,但一行高级编程语言可能会转成几十条二进制指令,为了做到这种复杂转换Hopper 在 1952 年创造了第一个编译器。 编译器专门把高级语言 转成低级语言,比如汇编或机器码(CPU 可以直接执行机器码)。 尽管"使编程更简单"很诱人,但很多人对霍普的点子持怀疑态度。 所以我们用 Python 举例(一门现代编程语言)。 假设我们想相加两个数字,保存结果。 记住,如果用汇编代码,我们得从内存取值,和寄存器打交道,以及其他底层细节。 如今大多数编程语言都是这样,不必接触 CPU 特有的汇编码和机器码,不必接触 CPU 特有的汇编码和机器码,减小了使用门槛。 感谢这些语言,计算机科学从深奥学科变成了大众化工具。同时,编程的抽象也让计算机专家,现在叫"专业程序员",制作更复杂的程序。如果用汇编写可能要上百万行。
R ——查看和修改寄存器 D ——查看内存单元 E ——修改内存单元 U ——反汇编,将机器指令变为汇编指令 T / P ——单步执行 G ——连续执行程序 A ——输入汇编指令 Q ——退出 简单的
学习编程其实就是学高级语言,即那些为人类设计的计算机语言。 但是,计算机不理解高级语言,必须通过编译器转成二进制代码,才能运行。学会高级语言,并不等于理解计算机实际的运行步骤。 ? 计算机真正能够理解的是低级语言,它专门用来控制硬件。汇编语言就是低级语言,直接描述/控制 CPU 的运行。如果你想了解 CPU 到底干了些什么,以及代码的运行步骤,就一定要学习汇编语言。 汇编语言不容易学习,就连简明扼要的介绍都很难找到。下面我尝试写一篇最好懂的汇编语言教程,解释 CPU 如何执行代码。 ? 一、汇编语言是什么? 我们知道,CPU 只负责计算,本身不具备智能。 编译器的作用,就是将高级语言写好的程序,翻译成一条条操作码。 对于人类来说,二进制程序是不可读的,根本看不出来机器干了什么。为了解决可读性的问题,以及偶尔的编辑需求,就诞生了汇编语言。 ? 汇编语言是二进制指令的文本形式,与指令是一一对应的关系。比如,加法指令00000011写成汇编语言就是 ADD。只要还原成二进制,汇编语言就可以被 CPU 直接执行,所以它是最底层的低级语言。
1.汇编语言格式简介 以asm_run_seg.S为例: .equ BYTE_DELAY, 0x00100000 .equ GPIO_ADDR, 0xf0000000 .globl _start _ 格式为.equ GPIO_ADDR,0xf0000000 标签,比如_start是地址,标注某段程序的位置,为程序中跳转及分支语句提供的跳转入口。标号一般用大写字母表示,或下划线跟小写字母或单词。 在使用标号时后面跟冒号”:”,比如LOOP: ,_start: 一般汇编指令格式:指令 + 空格 + 寄存器 + “,”+寄存器 + “,” + 寄存器(或立即数),比如 ADDI t3,x0,0;。 也有部分汇编指令只接一个寄存器和立即数,格式为指令 + 空格 + 寄存器 + “,”+ 立即数,比如 LI a3,0x08; 汇编指令以分号”;”结束,常量定义以回车换行结束,没有分号”;”。 比如.equ GPIO_ADDR, 0xf0000000和ADDI t3,x0,0; #后跟的内容是注释语句,对该指令或该段程序的说明或解释,编译器在编译时忽略该部分内容。
ARM汇编语言 模块结构 模块示例 ENTRY 指令 start 应用程序执行 stop 应用程序终止 END 指令 调用子例程 ALU 状态标记 条件执行 模块结构 ARM汇编语言是指 ARM 汇编程序 (armasm) 进行分析并汇编生成对象代码的语言。 ARM汇编语言的源代码行的一般格式是: {label标签} {instruction|directive|pseudo-instruction指令/伪操作/伪指令} {;comment语句注释} 标签是表示地址的符号 ARM汇编程序由段组成,段是相对独立的指令或数据单位,每个段由AREA伪指令定义,并定义段的属性。 ENTRY 指令 ENTRY 标记的是第一个要执行的指令。 每个汇编语言源模块必须以仅包括 END 指令的一行结束。
使用RISC-V 汇编语言,编写一个led 跑马灯的实验 程序分析: LI x8, 0xf0000000; # 设置gpio address; LI是伪指令,可被编译器翻译成LUI risc-v汇编指令集内无专门用来清零的指令。 LI x7, 0x00400000; # x7 设置delay counter 将值0x0040_0000存储到x7寄存器中。 编译器不会编译“#”后的语句。 该指令把x0的值和0x80相加,将和存到x10里。因为x0的值为0,实际上效果使把值0x80存到x10寄存器里。X10寄存器被用来点亮和熄灭LED。 程序里通过loop循环来实现。 为了应对全是0的情况就需要BEQ语句。当x10全是0时跳转到start也就是程序一开始的位置。X10的值被赋值为0x80。
在高级语言,如OC、C中,操作的对象是变量,而在ARM汇编语言中,操作的对象是寄存器(register)、内存(RAM)、栈(stack)。 CPU自带的变量,数量有限,需要更多的时候会把他们放到内存中 内存 - 变量存储的主要载体,容量大,但是对内存的操作要比对寄存器的操作慢得多 栈 - 其实本质也是内存,有特定的读写顺序:先进后出,而且ARM
0 push ax mov ax,7e00h push ax retf mov ax,4c00h int 21h ;org 7e00h ;引导程序 ],1 change_end: add bx,2 loop next pop cx pop bx ret clear_kb_buffer: ;1号程序 jmp show_line_start show_line_end: pop si pop di pop ax ret boot_end:nop ;转存引导程序 copy_boot: ;将引导程序储存到指定位置 mov ax,0 mov es,ax mov di,7e00h mov ax,cs mov .html 总结 汇编的难度并不大,我认为在有编程的基础上,学习汇编要做到细致,细致的理解计算机编程的编译过程,对于我理解其他编程语言也有很大的帮助。
7e00h 17 push ax 18 retf 19 20 mov ax,4c00h 21 int 21h 22 ;org 7e00h 23 ;引导程序 loop next 294 295 pop cx 296 pop bx 297 ret 298 299 clear_kb_buffer: 300 ;1号程序 CS 314 ;当程序转移到7c00h时,代码中CS值未发生改变, 315 ;所以需要我们指明段地址 316 mov bx,0b800h 317 mov es,bx 318 379 copy_boot: 380 ;将引导程序储存到指定位置 381 mov ax,0 382 mov es,ax 383 mov di,7e00h 384 .html 总结 汇编的难度并不大,我认为在有编程的基础上,学习汇编要做到细致,细致的理解计算机编程的编译过程,对于我理解其他编程语言也有很大的帮助。
说道汇编语言的产生,就不得不谈谈机器语言。机器语言(machine language)是一种指令集的体系。这种指令集是电脑的CPU可直接解读的数据。 汇编语言由以下3类指令组成: +汇编指令:机器指令的助记符,有对应的机器指令。 +伪指令:没有对应的机器码,由编译器执行,计算机不执行。 +其他符号:如+、-、*、/等,由编译器执行,计算机不执行。
参考书籍《汇编语言》王爽 著/清华大学出版社 一、基础知识 1、汇编指令是机器指令的助记符,同机器指令一一对应 2、每一种CPU都有自己的汇编指令集 3、CPU可以直接使用的信息在存储器中存放 通用寄存器又可分定点数和浮点数两类,它们用来保存指令执行过程中临时存放的寄存器操作数和中间(或最终)的操作结果。 通用寄存器是cpu的重要部件之一。 其结构有两种:一种是以微存储为核心的微程序控制方式;一种是以逻辑硬布线结构为主的控制方式。 2、对程序员来说,CPU中最主要部件是寄存器,可以通过改变寄存器的内容来实现对CPU的控制; 不同的cpu,寄存器的个数、结构是不同的。 5、汇编指令举例 ? 接下来看一下CPU执行下图中的每条指令后,对寄存器中的数据进行的改变: 说明,假设原AX中的值:0000H, 原BX中的值:0000H ?
汇编指令 1.mov指令 mov是一个传送指令,可以实现以下操作: 将数据传给寄存器,比如:mov al,10H 将寄存器中的值传给寄存器,比如mov ax,bx 将内存单元中的值传给寄存器,比如mov 4.loop指令 loop在汇编中用作循环,会执行标号到loop之间的部分,循环结束条件是cx寄存器的值为0。下面是一个例子,令ax寄存器中的值累加6次。 循环部分的执行流程为,遇到loop指令的时候,(cx)先减1,如果(cx)==0,则循环结束,执行下一条语句,否则调到标号对应的位置。 原因很简单,在第一次遇到标号s对应的汇编指令时,该指令会执行一次,无视标号。(标号并不是指令,只是起到指示地址的作用,编译后会被转化为实际的地址。) 举个例子: and ax,0000000011111111B or bl,11111111B 汇编中的数据 汇编语言支持数字型数据和字符型数据。
腾讯FPGA云服务器是基于FPGA硬件可编程加速的弹性计算服务,您只需几分钟就可以获取并部署您的FPGA实例。结合IP市场提供的图片,视频,基因等相关领域的计算解决方案,提供无与伦比的计算加速能力……
扫码关注云+社区
领取腾讯云代金券