adr r0, _start ldr r0, =_start nop mov pc, lr _start: nop 得出以下汇编 c008014 <_start> //ldr指令(不带=) : r0= c008014里面内容= e1a00000 c008004: e28f0008 add r0, pc, #8 ; 0x8 //adr指令: r0=(当前PC值+8)+0x8=c008014 c008008: e59f0008 ldr r0, [pc, #8] ; c008018 <_start e1a0f00e mov pc, lr 0c008014 <_start>: c008014: e1a00000 nop (mov r0,r0) c008018: 0c008014 stceq 0, cr8,
本篇介绍 本篇介绍下汇编中的宏和IO操作,其中IO操作包括控制台IO和文件IO 宏 首先宏并不是汇编支持的,而是nasm 汇编器支持的,这个也容易想到,汇编本身是一套指令,而宏就是将若干指令替换成一个符号 接下来看一个代码例子,nasm汇编的使用; ; macro.asm extern printf %define double_it(r) sal r, 1 ; single line macro 00 00 40113e: 48 be 38 40 40 00 00 movabs rsi,0x404038 401145: 00 00 00 401148: 48 8b mov eax,0x0 401155: e8 d6 fe ff ff call 401030 <printf@plt> 40115a: 48 8b 04 25 00 00 401177: 48 be 4e 40 40 00 00 movabs rsi,0x40404e 40117e: 00 00 00 401181: 48 8b
字型数据用两个单元存放,高地址单元放高8位,低地址单元放低8位。
dw offset func4-offset boot+7e00h time db 'YY/MM/DD hh:mm:ss',0 cmos db 9,8,7,4,2,0 zhidao.baidu.com/question/564008138.html int 16的1号程序:https://zhidao.baidu.com/question/511189643.html 总结 汇编的难度并不大 ,我认为在有编程的基础上,学习汇编要做到细致,细致的理解计算机编程的编译过程,对于我理解其他编程语言也有很大的帮助。
4 汇编语言程序设计 表达式中的运算符和操作符在 x86 汇编语言中的用法。 表达式 表达式是由常数、变量、操作符和运算符组合而成的计算公式。
stack segment 3 db 128 dup (0) 4 stack ends 5 code segment 6 start: 7 mov ax,stack 8 dw offset func4-offset boot+7e00h 37 time db 'YY/MM/DD hh:mm:ss',0 38 cmos db 9,8,7,4,2,0 zhidao.baidu.com/question/564008138.html int 16的1号程序:https://zhidao.baidu.com/question/511189643.html 总结 汇编的难度并不大 ,我认为在有编程的基础上,学习汇编要做到细致,细致的理解计算机编程的编译过程,对于我理解其他编程语言也有很大的帮助。
汇编语言设计程序篇-03 用汇编语言写的源程 用汇编语言编写程序的工作过程 程序中的三种伪指令 源程序经编译连接后变为机器码 汇编程序的结构 如何写出一个程序来? 段前缀的使用 在代码段中使用数据 应用案例 在代码段中使用栈 以数据逆序存放为例 数据逆序存放程序 在Debug中的执行结果 将数据、代码、栈放入不同 段 在Debug中执行 ---- 本系列文章参考汇编语言第四版和汇编语言程序设计 贺利坚主讲整理而成 ---- 用汇编语言写的源程序 用汇编语言编写程序的工作过程 ---- 程序中的三种伪指令 CS:IP寄存器是定位代码段位置的 ---- 源程序经编译连接后变为机器码 - --- 汇编程序的结构 在Debug中直接写入指令编写 的汇编程序 适用于功能简单、短小精悍的程序 只需要包含汇编指令即可 单独编写成源文件后再编译为可执行文件的程序 适用于编写大程序 需要包括汇编指令 由写出源程序到执行可执行文件的过程 ---- 编译 ---- 提示语法错误 ---- 连接 ---- 执行可执行程序 ---- 小结 ---- 运行及跟踪 这一节主要来看看程序加载进内存后的执行过程: 先准备一个汇编程序
本文主要介绍汇编语言程序设计中跑马灯程序的设计要求,GPIO的概念和相关硬件知识,为之后分析汇编程序做准备。 1. 跑马灯的设计: 使用汇编语言实现跑马灯。 程序设计要求: 假设系统时钟50Mhz,状态机版本RISC-V CPU约每3个时钟周期执行一条指令。 设计要求:系统中有8个LED(汇编语言代码中使用寄存器x10),在risc-v cpu 的硬件连接中, 我们将 LED[7:0] 连接到 risc-v cpu GPIO外设的A组外设寄存器[7:0], 因为LED在开发板上采用共阳极方式设计,所以FPGA管脚为低电平时LED点亮。如下图原理图中所示。 图1. 理论上一个地址可以控制32个gpio管脚,但是实际上在开发板上只能控制8个管脚,因为硬件上只给cpu留了8个管脚的资源,在该cpu的0xf000_0000地址上只有低8位的值是有用的。
Win8下用DOSBox编写汇编语言 DOSBox 是一个 DOS模拟程序,可以很方便的移植到其他的平台,因此可以使用它在Win8系统中编写汇编语言。 下面提供相关下载链接: DOSBox下载: http://pan.baidu.com/s/1qWwkss0 汇编工具下载: http://pan.baidu.com/s/1i3taKmT DOSBox使用指南: (1)在你的磁盘上新建一个存放自己代码的目录,如:我在E盘下新建一个目录DOS,那么我的工作目录即为:E:\DOS,以后我写的汇编代码就会存放在这个目录下。 (2)选中上面汇编工具的链接(按下Ctrl,鼠标左键单击即可),下载汇编工具。 :\DOS(回车) ;注意这里E:\DOS是你之前创建的工作目录,根据自己的目录输入 第二步: C:(回车) 前两步执行结果如下图, 这样我们就进入了类似win7下DOS的环境,在这里就可以编写汇编程序了
1.汇编语言格式简介 以asm_run_seg.S为例: .equ BYTE_DELAY, 0x00100000 .equ GPIO_ADDR, 0xf0000000 .globl _start _ = x7) goto loop ADDI t3, x0, 0; # t3 = 0 汇编的指示符(directive)的格式使用“.” + 关键词 .globl(注意不是.global 在使用标号时后面跟冒号”:”,比如LOOP: ,_start: 一般汇编指令格式:指令 + 空格 + 寄存器 + “,”+寄存器 + “,” + 寄存器(或立即数),比如 ADDI t3,x0,0;。 也有部分汇编指令只接一个寄存器和立即数,格式为指令 + 空格 + 寄存器 + “,”+ 立即数,比如 LI a3,0x08; 汇编指令以分号”;”结束,常量定义以回车换行结束,没有分号”;”。
设计介绍 单片机介绍 51单片是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。 在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C51为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。 具有以下标准功能:8k字节Flash,512字节RAM,32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口 设计内容 01 仿真图 本设计利用protues8.7软件实现仿真设计,具体如图。 02 程序 本设计由汇编语言编写,主代码具体如下: ORG 0000H LJMP MAIN ORG 0003H LJMP JIAYI ORG 0013H LJMP JIANYI ORG
具体实现功能: 通过5个8*8led点阵显示数字时间,显示时分,从12点开始计时,显示时间格式为:12::00。 设计介绍 单片机介绍 51单片是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。 设计内容 01 仿真实现 本设计利用protues8.7软件实现仿真设计,具体如图。 Protues也是在单片机仿真设计中常用的设计软件之一,通过设计出硬件电路图,及写入驱动程序,就能在不实现硬件的情况进行电路调试。 02 汇编程序 本设计由汇编语言编写,主代码具体如下: ORG 0000H LJMP MAIN ORG 0003H LJMP PINT0 ORG 000BH
使用RISC-V 汇编语言,编写一个led 跑马灯的实验 程序分析: LI x8, 0xf0000000; # 设置gpio address; LI是伪指令,可被编译器翻译成LUI 指令,该指令把值0xf000_0000存放到寄存器x8里,目的是把gpio的地址存储到x8寄存器中以便之后使用。 risc-v汇编指令集内无专门用来清零的指令。 LI x7, 0x00400000; # x7 设置delay counter 将值0x0040_0000存储到x7寄存器中。 因为led是共阳设计,一端已经是3.3V高电平,led7对应的GPIO接口如果是1,led7不会被点亮。反而其他led灯会被点亮,因为led6-0此时为低电平。所以需要把x10的值整体取反。 SH x18, 0(x8); # addr[0xf000_0000] = val[0x18] 把x18的值存到一个地址上,地址由x8的值和立即数0相加得到。
具体实现功能: 主持人按下抢答按键后,进入抢答模式,8位选手开始抢答,数码管显示抢答成功的选手号码,主持人按键再次按下后复位。 设计介绍 单片机介绍 51单片是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。 在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C51为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。 Protues也是在单片机仿真设计中常用的设计软件之一,通过设计出硬件电路图,及写入驱动程序,就能在不实现硬件的情况进行电路调试。 02 汇编程序 本设计由汇编语言编写,主代码具体如下: ORG 000 JMP BEGIN TABLE:
(5)提供足够的调用信息: 1.寄存器传送参数 2.存储器传送参数 3.堆栈传送参数 模块化设计 ---- 汇编语言程序设计技巧 四种基本结构:顺序结构、分支结构、循环结构和子程序。 PC ← A+DPTR TAB: AJMP SUB0 ;转移指令表 AJMP SUB1 AJMP SUB2 …… AJMP SUB6 3、循环结构 循环程序结构是汇编语言程序中常见的一种程序结构 子程序设计 (1)子程序入口用标号作为子程序名。 (2)调用子程序之前设置好堆栈。 (3)用返回指令RET结束子程序,并保证堆栈栈顶为调用程序的返回地址。 (4)子程序嵌套须考虑堆栈容量。 DJNZ R6,DL1 DJNZ R7,DL2 RET END 模块化设计 模块化设计是指把一个具体的功能分解成多个小的模块,各个模块之间相互独立,而又可以相互传递参数。
segmentstart: mov ax,a mov ds,ax mov ax,b mov es,ax mov bx,0 mov cx,8s al inc bx loop s mov ax,c mov es,ax mov bx,0 mov cx,8s0 loop s0 mov ax,4c00h int 21hcode endsend start运行结果:4、程序如下,编写code段中的代码,用push 指令将a段中的钱8个字符型数据 assume cs:code a dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh a ends b segment dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 mov ds,ax mov ax,b mov ss,ax mov sp,10h mov bx,0 mov cx,8s
MIPS汇编中的分段处理 .data #数据段 .text #代码段 传送指令 加载立即数指令 li li(load immediate) :用于将立即数传送给寄存器 li $t0,1 ;十六进制数据使用 move 用于将一个寄存器中的数据传送至另一个寄存器当中 move $t0,$t1 # 将寄存器$t1中的数据传送至$t0 系统服务指令 syscall 在C语言中输出文本可以使用printf函数,但是汇编中没有 双精度数(double型)在32位计算机中存储占用8字节,也就是64位,有效位数为16位,小数点后15位。 : scanf("%d",$a); scanf("%d",$b); if(a>b){ printf("YES"); }else{ printf("NO"); } 汇编代码: # 用$t0 ,如果我们要依次打印1,2,3三个整数,那么汇编如下: print1: li $v0,1 li $a0,1 syscall jr $ra print2: li $v0,1 li $a0,2
汇编语言--高级汇编技术 子程序的封装 程序的多文件组织 汇编指令汇 数据传送指令 算术指令 逻辑指令 串处理指令 控制转移指令 处理机控制与杂项操作指令 汇编伪操作汇 处理机选择伪操作 段定义伪操作 .exe的诞生 程序运行步骤及生成的文件 汇编过程 宏汇编 C语言中的预处理命令 汇编中的宏---由C中的宏定义说起 举例 语法和术语 子程序VS宏定义 宏中的局部标号 变元是操作码的一部分 宏库 条件汇编 BYTE_ARRAY标号来操作这块内存时,会按字节为单位进行操作 ---- 表达式赋值伪操作 表达式名 EQU 表达式 ALPUA EQU 9 BETA EQU ALPUA+18 BB EQU [BP+8] 因此从10地址处进行分配 VAR1 DW 1234H ORG 20 //从20地址处开始分配 VAR2 DW 5678H //$为上面一条指令的地址 ORG $+8 //在$地址的基础上,加8,然后再对应的地址分配下面这个变量内存空间 VAR3 DW 1357H ALIGN伪操作: 包装数组边界从2的整数次幂地址开始 EVEN伪操作: 使下一个变量或指令开始与偶数字节地址
本篇介绍 本篇作为汇编系列的开篇,就先研究下汇编如何写helloworld。 在section .data段用来定义变量,格式如下 <variable name> <type> <value> 类型如下: type length name db 8 bits Byte dw 16 ,格式如下: <variable name> <type> <name> 比如下面是定义了一个 20字的数组 dArray resd 20 类型如下: type length names resb 8 global main 7 main: 8 这样就完成了汇编helloworld的学习了。
int 21h codesg ends end 开头和结尾的两句代表伪指令 只有编译器可以读懂 汇编指令可以被翻译为机器码最终被cpu执行 汇编程序 就是包含汇编指令和伪指令的文本 mov ax,4c00h int 21h 跟C语言程序的return 0一样 返回控制权 一个汇编程序是由多个段组成的 这些段被用作各种空间来使用 一个有意义的汇编程序至少需要一个段 且每个段都需要段名 段名 segment- 255 16位寄存器的范围是65535 可以在dx中存放 不可以将内存字节单元累加到dx 因为dx是十六位 所以如果要用add 则我们需要取出内存字单元 而我们需要的是内存字节单元 dl也不行 累加十二个8位数据到一个 8位寄存器 会导致进位丢失 可以这样做 mov al,ds:[addr] mov ah,0 add dx,ax 这样我们既可以存放下数据 同时也不会因为字单元数据 累加到错误的数据 我们继续完成上面那个示例 assume cs:code code segment dw 0123h,0456h,0abch,0defh,0fedh,0cbah,0987h start:mov bx,0 mov ax,0 mov cx,8