当前位置:文档之家› ARM GUN 伪指令

ARM GUN 伪指令

ARM GUN 伪指令
ARM GUN 伪指令

1.宏定义

.macro 宏名 参数名列表 @伪指令.macro定义一个宏

宏体

.endm @.endm表示宏结束

如果宏使用参数,那么在宏体中使用该参数时添加前缀“\”。宏定义时的参数还可以使用默认值。 可以使用.exitm伪指令来退出宏。

2.段定义

section伪操作

用户可以通过.section伪操作来自定义一个段,格式如下:

.section section_name [, "flags"[, %type[,flag_specific_arguments]]]

flag的值为 a 允许段 w 可写段 x 执行段

预定义的段名 .text @代码段 .data @初始化数据段 .bss @未初始化数据段

定义入口点 :

.globl _start

_start:

注意: 源程序中.bss段应该在.text之前

当用预定义段名可以直接使用,当是自定义时段定义要完整。

3.数据定义伪操作: .byte 1b,.short 2b,.long 4b,.quad 8b,.float,.string/.asciz/. ascii,重复定义伪操作.rept,赋值语句.equ/.set

注意:.ascii伪操作定义的字符串需要自行添加结尾字符'\0'

4. 函数定义伪操作:格式

函数名:

函数体

返回语句

一般的,函数如果需要在其他文件中调用, 需要用到.global伪操作将函数声明为全局函数。为了不至于在其他程序在调用某个C函数时发生混乱,对寄存器的使用我们需要遵循APCS准则。函数编译器将处理为函数代码为一段.global的汇编码。

5.常数

1)十进制数以非0数字开头,如:123和9876;

2)二进制数以0b开头,其中字母也可以为大写;

3)八进制数以0开始,如:0456,0123;

4)十六进制数以0x开头,如:0xabcd,0X123f;

5)字符串常量需要用引号括起来,中间也可以使用转义字符,如: "You are welcome!\n";

6)当前地址以"."表示,在汇编程序中可以使用这个符号代表当前指令的地址;

7)表达式:在汇编程序中的表达式可以使用常数或者数值, "-"表示取负数, "~"表示取补,"<>"表示不相等,其他的符号如:+、-、*、/、%、<、<<、>、>>、|、&、^、!、==、>=、<=、&&、||跟C语言中的用法相似。

6.Linux 汇编程序中的标号

标号只能由a~z,A~Z,0~9,".",_等字符组成。当标号为0~9的数字时为局部标号,局部标号可以重复出现,使用方法如下:

标号f: 在引用的地方向前的标号

标号b: 在引用的地方向后的标号

【例2】使用局部符号的例子,一段循环程序

1:

subs r0,r0,#1 @每次循环使r0=r0-1

bne 1f @跳转到1标号去执行

局部标号代表它所在的地址,因此也可以当作变量或者函数来使用。

7..align .end .include .incbin伪操作

1).align:用来指定数据的对齐方式,格式如下:

.align [absexpr1, absexpr2]

以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或 32. 第二个表达式值表示填充的值。

2).end:表明源文件的结束。

3).include:可以将指定的文件在使用.include 的地方展开,一般是头文件,例如:

.include "myarmasm.h"

4).incbin伪操作可以将原封不动的一个二进制文件编译到当前文件中,使用方法如下:

.incbin "file"[,skip[,count]]

skip表明是从文件开始跳过skip个字节开始读取文件,count是读取的字数.

8..global .type .title .list

1).global/ .globl :用来定义一个全局的符号,格式如下:

.global symbol 或者 .globl symbol

2).type:用来指定一个符号的类型是函数类型或者是对象类型, 对象类型一般是数据, 格式如下:

.type 符号, 类型描述

3)列表控制语句:

.title:用来指定汇编列表的标题,例如: .title "my program"

.list:用来输出列表文件.

9.ARM特有的伪操作

1) .reg: 用来给寄存器赋予别名,格式如下:

别名 .req 寄存器名

2) .unreq: 用来取消一个寄存器的别名,格式如下:

.unreq 寄存器别名

注意被取消的别名必须事先定义过,否则编译器就会报错,这个伪操作也可以用来取消系统预制的别名, 例如r0, 但如果没有必要的话不推荐那样做。

3) .code伪操作用来选择ARM或者Thumb指令集,格式如下:

.code 表达式

如果表达式的值为16则表明下面的指令为Thumb指令,如果表达式的值为32则表明下面的指令为ARM指令.

4) .thumb伪操作等同于.code 16, 表明使用Thumb指令, 类似的.arm等同于.code 32

5) .force_thumb伪操作用来强制目标处理器选择thumb的指令集而不管处理器是否支持

6) .thumb_func伪操作用来指明一个函数是thumb指令集的函数

7) .thumb_set伪操作的作用类似于.set, 可以用来给一个标志起一个别名, 比.set功能增加的一点是可以把一个标志标记为thumb函数的入口, 这点功能等同于.thumb_func

8) .ltorg用于声明一个数据缓冲池(literal pool)的开始,它可以分配很大的空间。

9) .pool的作用等同.ltorg

9).space {,}

分配number_of_bytes字节的数据空间,并填充其值为fill_byte,若未指定该值,缺省填充0。(与armasm中的SPACE功能相同)

10).word {,} ?

插入一个32-bit的数据队列。(与armasm中的DCD功能相同)

可以使用.word把标识符作为常量使用

例如:

Start:

valueOfStart:

.word Start

这样程序的开头Start便被存入了内存变量valueOfStart中。

11).hword {,} ?

插入一个16-bit的数据队列。(与armasm中的DCW相同)

10..if伪操作

根据一个表达式的值来决定是否要编译下面的代码, 用.endif伪操作来表示条件判断的结束, 中间可以使用.else来决定.if的条件不满足的情况下应该编译哪一部分代码。

.if有多个变种:

.ifdef symbol @判断symbol是否定义

.ifc string1,string2 @字符串string1和string2是否相等,字符串可以用单引号括起来

.ifeq expression @判断expression的值是否为0

.ifeqs string1,string2 @判断string1和string2是否相等,字符 串必须用双引号括起来

.ifge expression @判断expression的值是否大于等于0

.ifgt absolute expression @判断expression的值是否大于0

.ifle expression @判断expression的值是否小于等于0

.iflt absolute expression @判断expression的值是否小于0

.ifnc string1,string2 @判断string1和string2是否不相等, 其用法跟.ifc恰好相反。

.ifndef symbol, .ifnotdef symbol @判断是否没有定义symbol, 跟.ifdef恰好相反

.ifne expression @如果expression的值不是0, 那么编译器将编译下面的代码

.ifnes string1,string2 @如果字符串string1和string2不相 等, 那么编译器将编译下面的代码.

汇编常用伪指令

一、基本段定义格式常用结构STACK SEGMENT PARA 'STACK; DB 100 DUP('STACK') STACK ENDS DATA SEGMENT DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK START: MOV AX,data MOV DS,AX MOV ES,AX MOV AL,4CH INT 21H CODE ENDS END START ------------------------------------------------------------------------------------------------------------------------ 段名segment[定位][组合][段字][‘类别’] ... 段名ends (1)定位 段定位(align)属性——指定逻辑段在主存储器中的边界: BYTE:段开始为下一个可用的字节地址(xxxx xxxxb),属性值为1 WORD:段开始为下一个可用的偶数地址(xxxx xxx0b),属性值为2 DWORD:段开始为下一个可用的4倍数地址(xxxx xx00b),属性值为4 PARA:段开始为下一个可用的节地址(xxxx 0000b),属性值为16 PAGE:段开始为下一个可用的页地址(0000 0000b),属性值为256 简化段定义伪指令的代码和数据段默认采用WORD定位,堆栈段默认采用PARA定位。完整段定义伪指令的默认定位属性是PARA。(2)组合 PUBLIC: 所有此类型的同名段组合成一个逻辑段,公用一个段地址,运行时装入同一个物理段中。 COMMON : 所有此类型的同名段具有相同的起始地址(覆盖),共享相同的存储区域。 AT <数值表达式> : 按绝对地址定位,段地址就是表达式的值。

ARM伪指令详述

1、AREA 语法格式: AREA 段名属性1,属性2,…… AREA伪指令用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用―|‖括起来,如|1_test|。 属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。常用的属性如下:— CODE属性:用于定义代码段,默认为READONL Y。 — DATA属性:用于定义数据段,默认为READWRITE。 — READONL Y属性:指定本段为只读,代码段默认为READONL Y。 — READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE。—ALIGN属性:使用方式为ALIGN 表达式。在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐的,表达式的取值范围为0~31,相应的对齐方式为2表达式次方。—COMMON属性:该属性定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的COMMON段共享同一段存储单元。 一个汇编语言程序至少要包含一个段,当程序太长时,也可以将程序分为多个代码段和数据段。 使用示例: AREA Init,CODE,READONL Y 指令序列 ;该伪指令定义了一个代码段,段名为Init,属性为只读 2、ALIGN 语法格式: ALIGN {表达式{,偏移量}} ALIGN伪指令可通过添加填充字节的方式,使当前位置满足一定的对其方式|。其中,表达式的值用于指定对齐方式,可能的取值为2的幂,如1、2、4、8、16等。若未指定表达式,则将当前位置对齐到下一个字的位置。偏移量也为一个数字表达式,若使用该字段,则当前位置的对齐方式为:2的表达式次幂+偏移量。 使用示例: AREA Init,CODE,READONL Y,ALIEN=3 ;指定后面的指令为8字节对齐。 指令序列 END 3、CODE16、CODE32 语法格式: CODE16(或CODE32) CODE16伪指令通知编译器,其后的指令序列为16位的Thumb指令。 CODE32伪指令通知编译器,其后的指令序列为32位的ARM指令。 若在汇编源程序中同时包含ARM指令和Thumb指令时,可用CODE16伪指令通知编译器其后的指令序列为16位的Thumb指令,CODE32 伪指令通知编译器其后的指令序列为32位的ARM指令。因此,在使用ARM指令和Thumb指令混合编程的代码里,可用这两条伪指令进行切换,但注意他们只通知编译器其后指令的类型,并不能对处理器进行状态的切换。使用示例: AREA Init,CODE,READONL Y …… CODE32 ;通知编译器其后的指令为32位的ARM指令

IA-32中常见的伪指令

TITLE 伪指令将整行标为注释 INCLUDE伪指令后跟文件名,指定从某一文件中拷贝必需的信息 .code伪指令用来标记代码段的开始,程序中所有可执行语句都放于此处 PROC伪指令允许声明一个过程并且附带参数列表,其使用格式为 label PROC { [,parameter_1] } 每个参数的格式为参数名:类型 ENDP伪指令标识子程序的结束 END伪指令标明该行是汇编程序的最后一行,编译器将忽略该行后面的所有内容 .386伪指令指出了程序要求的最低CPU(Intel386) .MODEL伪指令指示编译器哪种模式程序生成代码 STDCALL伪指令允许程序调用MS-Windows函数 PROTO伪指令声明了程序使用的子程序 INVOKE是一个用于调用过程或函数的汇编伪指令 BYTE,SBYTE等类似的,用于定义数据的伪指令。早期还是用DB,但DB无法区分是否有符号DUP操作使用一个常量表达式作为计数器来重复分配存储空间。即使用DUP可以一次分配多个空间,并且决定对此空间进行全部初始化或全部都不初始化 .DAT A伪指令可用于声明未初始化数据,它在定义大块的未初始化数据时非常有用,因为它可以缩小编译后的程序尺寸 =(等号伪指令)将符号名和整数表达式联系起来。以=定义的符号可重定义任意多次EQU伪指令将符号名和整数表达式或任意文本联系起来。三种使用格式 name EQU expression 有效的整数表达式 name EQU symbol 已被=或EQU定义的符号 name EQU 用EQU定义的符号不能在同一源代码文件中重复定义 TEXTEQU伪指令可用来创建文本宏(text macro) OFFSET操作符返回一个变量相对于其所在段开始的偏移,即返回数据标号的偏移地址PTR操作符允许重载变量的默认尺寸 TYPE操作符返回数组中每个元素的大小(以字节计算) LENGTHOF操作符返回数组内元素的数目。注意对在DUP的嵌套使用和换行的情况SIZEOF操作符返回数组初始化时占用的字节数。即返回LENGTHOF和TYPE返回值的乘积ALLIGN伪指令将变量的位置按字节、字、双字边界对齐ALLIGN 1|2|4。数据对齐可能会浪费一部分存储空间,但CPU处理存储在偶数地址的数据比处理存储在奇数地址的 数据要快 LABEL伪指令允许插入一个标号并赋予其尺寸属性而无需分配任何实际的存储空间 JMP指令导致向代码段内的目标地址做无条件转移 LOOP指令提供了一种将程序块重复执行特定次数的简单方法。ECX被自动用作计数器。并且注意LOOP指令的执行是分两步:首先,ECX减1,接着与0比较。根据比较的 结果来决定是否发生跳转 .NOLIST伪指令禁止编译器在创建的列表文件中显示这些源文件行。 .LIST伪指令允许显示后面文件行 USES与PROC伪指令配套使用的USES操作符允许列出被过程修改的所有寄存器,它只是编译器做两件事情:首先,在过程的开始出生成PUSH指令在堆栈上保存寄存器;其 次,在过程的结束处生成POP指令恢复这些寄存器的值。 LOCAL伪指令在过程内声明一个或多个命名局部变量,语句必须紧跟在PROC伪指令所在行

汇编程序设计实验报告--完整段定义程序实现

《汇编语言程序设计》 实验报告

实验四完整段定义程序的实现实验目的 1、掌握完整段格式定义的程序设计方法; 2、掌握伪指令:SEGMENT、ENDS、ASSUME、END、OFFSET、DUP; 3、掌握汇编语言程序中指名程序入口的方法; 4、了解用INT 21H 的4C号功能调用返回系统的方法; 5、掌握用MASM、LINK工具进行汇编和链接的过程。 实验内容 要求程序中实现对键盘输入的字符作如下处理: ●如果输入的是小写字母则转换成对应的大写字母并显示在屏幕上; ●如果输入的是大写字母则转换成对应的小写字母并显示在屏幕上; ●如果输入的是键盘上的Esc键则退出程序执行; ●按其它任意可显示键,则不作处理,直接显示输出。 实验步骤 1、编辑下列程序: DATA SEGMENT ;数据段定义 MESSAGE DB 'Please input your key!',0DH,0AH,'$' DATA ENDS STACK SEGMENT PARA STACK 'STACK' ;堆栈段定义 DB 50 DUP(?) STACK ENDS CODE SEGMENT ;代码段 ASSUME CS:CODE,DS:DATA,SS:STACK ;分配段寄存器START: MOV AX,DATA MOV DS,AX MOV DX,OFFSET MESSAGE MOV AH,9 INT 21H ;显示提示信息 AGAIN: MOV AH,1 INT 21H ;读入一个键盘按键 CMP AL,1BH ;按的是ESC键(ASCII码为1BH)则退出程序 JE EXIT CMP AL,61H JB NEXT CMP AL,7AH

ARM的汇编指令讲解

汇编知识点的要求: 1、能看的懂 2、可以做修改 3、不需要用汇编直接编写程序 汇编代码的应用场合: 1、ARM的启动代码必须要汇编,如:uboot最开始初始化硬件的代码 2、内核在最开始初始化的位置。。。。 一、ARM汇编指令的编码格式 1、编码格式 ARM汇编指令编译成机器码以后,机器码的长度是32bits,这32bits的编码有一个固定的格式。不同ARM 汇编指令,编码格式不同。 2、举例 C: if(a==10) a++; else a--;

汇编1: CMP R0, #10; ADDEQ R0,R0,#1 SUBNE R0,R0,#1 汇编2 SUBS R1, R0, #10; //S ---运算的结果会影响条件码标志位:CPSR:NZCV ADDEQ R0,R0,#1 SUBNE R0,R0,#1 提示: 空指令NOP,实际上是占用CPU的时间,但是执行后,没有什么意义。 NOP ---- MOV R0,R0 3、条件码标识 10 -10 Z = 1 C = 0 N = 0 V = 0 ================================================================================= 二、ARM的寻址方式 1、立即数寻址 操作数,有立即数。 ADD R0,R0,#1

MOV R1,#10 ORR R1,R1,#0xf @ R1=R1 | 0xf BIC R1,R1,#0xf @R1 = R1&(~(0xf)) 错误: ADD R1,#1,#2 注意:立即数合法的条件 在ARM汇编指令中,并不是所有的立即数,立即数是有一定的限制的。 什么样的立即数是合法的??? 1、如果一个立即数是小于256的(即该立即数是8bits以内的,0~255),该立即数是合法的。 2、如果一个立即数是大于等于256,该立即数经过循环左移偶数位,可以得到一个小于256的数,则该立即数合法。 256 = 0x100 ------→左移20位0x10000000----→左移4 0x1 合法 0x111 非法 0x102 非法 0x104 合法 0xfff 0xff00 0x12000 0x450000 0xab 原因: 在数据处理指令编码的时候,立即数用12bits来表示: 高4bits:循环左移左移偶数位除以2 低8bits:循环左移后的结果。 重要问题: ADD R1,R0,#0xffff 非法 解决: LDR R2,=0xffff // R2=0xffff,将立即数0xffff的值传送给R2 ADD R1, R0, R2 2、寄存器寻址 所有的操作数都是寄存器,没有立即数 ADD R0,R0,R1 MOV R1,R0 ORR R1,R1,R0 @ R1=R1 | 0xf BIC R1,R1,R0 @R1 = R1&(~(0xf))

实验二 常用伪指令 2010214228

实验二常用伪指令的使用 一.实验目的: 进一步熟悉变量定义伪指令及各种运算符的使用。 二.实验内容: 调试实验指导中给出的程序,查看数据区的内容,回答相关问题。三.操作步骤 1.建立源程序文件如图3-1所示。 DATA SEGMENT ARRY1 DB 12,-18,32,68,-9 COUNT EQU $-ARRY1 ORG 08H ARRY2 DW 15,26,38 STR1 DB 'ABCD' DATA1 DW ARRY2 DATA2 DD ARRY2 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV AL,STR1 MOV BL,COUNT MOV DX,OFFSET ARRY2 MOV AX,SEG ARRY2 MOV BL, BYTE PTR DATA1+1 MOV BL,BYTE PTR DATA2 MOV CX,WORD PTR DATA2 MOV AH,4CH ; 调用21H号中断的4CH号功能,返回DOS INT 21H CODE ENDS END START 图2-1 2. 根据数据区定义画出数据区的存储示意图 地址内容变量名 0710:0000 0CH ARRY1 0710:0001 EEH 0710:0002 20H

0710:0003 44H 0710:0004 F7H 0710:0008 0FH ARRY2 0710:0009 00H 0710:000A 1AH 0710:000B 00H 0710:000C 26H 0710:000D 00H 0710:000E 41H STR1 0710:000F 42H 0710:0010 43H 0710:0011 44H 0710:0012 00H DA TA1 0710:0013 00H 0710:0014 08H DA TA2 0710:0015 00H 0710:0016 10H 0710:0017 07H 3.回答以下问题: 1)DATA段中DA TA1和DATA2里存放的数据的物理意义是什么? 答:DATA1中存放ARRY1的偏移地址,占一个字,低位字节占用第一个字节地址,高位字节占用第二个字节地址。DATA2存放ARRY2的段基址和偏移地址,偏移地址占用低位字,段基址占用高位字。 2)COUNT所表示的值是多少?其物理意义是什么? 答:COUNT用来计算ARRY1占用的字节数,其值是5 3)将STR1 DB'ABCD' 改为STR1 DW'ABCD' ,则STR1数据区的内容会发生 什么变化? 答:由DB改为DW后STR1数据区的内容为0041H,0042H,0043H,0044H 4. 单步运行程序中带下划线的语句,查看每一条语句运行后寄存器的变化,用准确的语言描述该指令所执行的操作。如:指令MOV AX,[BX] 执行的操作是将寄存器BX中的内容作为有效地址,将其所指向的连续两个字节的存储单元的内容送到AX 中。 答: 注:本次实验无须提交源程序文件,只提交实验报告即可。

ARM汇编语言源程序格式

ARM汇编语言源程序格式ARM汇编语言源程序格式2010-11-16 13:52 来源:MCU嵌入式领域 常用ARM源程序文件类型 汇编语言程序的结构1 汇编语言程序的结构2 汇编语言程序的结构3 汇编语言程序的结构4 ARM的汇编语言程序一般由几个段组成,每个段均由AREA伪操作定义。 段可以分为多种,如代码段、数据段、通用段,每个段又有不同的属性,如代码段的默认属性为READONLY,数据段的默认属性为READWRITE。 本程序定义了两个段,第一个段为代码段codesec,它在存储器中存放用于程序执行的代码以及main函数的本地字符串;第二个段为数据段constdatasec,存放了全局的字符串,由于本程序没有对数据进行写操作,该数据段定义属性为READONLY。 汇编语言的行构成1 格式: [标签]指令/伪操作/伪指令操作数[;语句的注释] 所有的标签必须在一行的开头顶格写,前面不能留空格,后面也不能跟C 语言中的标签一样加上":";

ARM汇编器对标识符的大小写敏感,书写标号及指令时字母的大小写要一致; 注释使用";"符号,注释的内容从";"开始到该行的结尾结束 汇编语言的行构成2 标签 标签是一个符号,可以代表指令的地址、变量、数据的地址和常量。 一般以字母开头,由字母、数字、下划线组成。 当符号代表地址时又称标号,可以以数字开头,其作用范围为当前段或者在下一个ROUT伪操作之前。 指令/伪操作 指令/伪操作是指令的助记符或者定义符,它告诉ARM的处理器应该执行什么样的操作或者告诉汇编程序伪指令语句的伪操作功能。 汇编语言的标号1 标号代表地址。 标号分为段内标号和段外标号。段内标号的地址值在汇编时确定,段外编号的地址值在链接时确定。 在程序段中,标号代表其所在位置与段首地址的偏移量。根据程序计数器(PC)和偏移量计算地址即程序相对寻址。 在映像中定义的标号代表标号到映像首地址的偏移量。映像的首地址通常被赋予一个寄存器,根据该寄存器值与偏移量计算地址即寄存器相对寻址。 例如:

STM 常用汇编指令

在嵌入式开发中,汇编程序常常用于非常关键的地方,比如系统启动时初始化,进出中断时的环境保护,恢复等对性能有要求的地方。 ARM指令集可以分为六大类,分别为数据处理指令、Load/Store指令、跳转指令、程序状态寄存器处理指令、协处理器指令和异常产生指令。 ARM指令使用的基本格式如下: 〈opcode〉{〈cond〉}{S}〈Rd〉,〈Rn〉{,〈operand2〉} opcode操作码;指令助记符,如LDR、STR等。 cond可选的条件码;执行条件,如EQ、NE等。 S可选后缀;若指定“S”,则根据指令执行结果更新CPSR中的条件码。 Rd目标寄存器。 Rn存放第1操作数的寄存器。 operand2第2个操作数 arm的寻址方式如下: 立即寻址 寄存器寻址 寄存器间接寻址 基址加偏址寻址 堆栈寻址 块拷贝寻址 相对寻址 这里不作详细描述,可以查阅相关文档。 数据处理指令 Load/Store指令 程序状态寄存器与通用寄存器之间的传送指令 转移指令 异常中断指令 协处理器指令 在S3C2410、S3C2440的数据手册中对各种汇编指令有详细的描述;这里只对较常见的作写介绍。 1、相对跳转指令:b、bl 这两条指令的不同之处在于bl指令除了跳转之外,还将返回地址(bl的下一条指令的地址)保存在lr寄存器中。 这两条指令的可跳转范围是当前指令前后32M。 b funa .... funa: b funb ....

funb: .... 2、数据传送指令mov,地址读取伪指令ldr mov指令可以把一个寄存器的值赋给另外一个寄存器,或者把一个常数赋给寄存器。 mov r1,r2 mov r1,#1024 mov传送的常数必须能用立即数来表示。当不能用立即数表示时,可以用ldr命令来赋值。ldr是伪命令,不是真实存在的指令,编译器会把它扩展成真正的指令;如果该常数能用“立即数”来表示,则使用mov指令,否则编译时将该常数保存在某个位置,使用内存读取指令把它读出来。 ldr r1,=1024 3、内存访问指令ldr、str、ldm、stm ldr既可以指低至读取伪指令,也可以是内存访问指令。当他的第二个参数前面有'='时标伪指令,否则表内存访问指令。 ldr指令从内存中读取数据到寄存器,str指令把寄存器的指存储到内存中,他们的操作数都是32位的。 ldr r1,[r2,#4] ldr r1,[r2] ldr r1,[r2],#4 str r1,[r2,#4] str r1,[r2] str r1,[r2],#4 寄存器传送指令可以用一条指令将16个可见寄存器(R0~R15)的任意子集合(或全部)存储到存储器或从存储器中读取数据到该寄存器集合中。与单寄存器存取指令相比,多寄存器数据存取可用的寻址模式更加有限。多寄存器存取指令的汇编格式如下: LDM/STM{}Rn{!}, 4、加减指令add、sub add r1,r2,#1 sub r1,r2,#1 5、程序状态寄存器的访问指令msr,mrs ARM指令中有两条指令,用于在状态寄存器和通用寄存器之间传送数据。修改状态寄存器一般是通过“读取-修改-写回”三个步骤的操作来实现的。这两条指令分别是: 状态寄存器到通用寄存器的传送指令(MRS) 通用寄存器到状态寄存器的传送指令(MSR) 其汇编格式如下: MRS{}Rd,CPSR|SPSR 其汇编格式如下:

伪指令

A51汇编解释---伪指令 2011-05-11 17:51:46| 分类:默认分类| 标签: |举报 |字号大 中 小订阅 一:定义符号的伪指令 1)SEGMENT 格式: 段名符号 SEGMENT 段类型 [再定位类型] SEGMENT指令可声明一个可再定位(区别于CSEG,DSEG,XSEG,BSEG,ISEG等定义的在相对应的空间固定地址定义的绝对段—在连接的过程中不允许重新定位)的段符号和一个可选的再定位类型,段符号可以用来定义段,L51连接器可将多个模块内的具有相同段名和再定位类型的几个段合成为一个段.段类型说明了段所处的地址空间. 如果是编写的汇编程序要与C源程序接口,即被C源程序调用,则全部的汇编子程序所命名的定义的代码段的段名必须是可用SEGMENT来定义的,而且名字的命名的方法也应该参照C51编译器产生的局部段的段名的转换规则.段名的作用主要是在汇编的时候用RSEG来激活的,在连接定位的时候用到的.与段名相应的是用于存储和传递参数的别名,可以在汇编源程序中直接应用局部段的别名,这个别名主要是在传递函数参数的时候用的.在汇编程序中要用PUBLIC 声明被其他模块引用的全局符号. DATA (可直接寻址的内部RAM空间) IDATA (可间接寻址的内部RAM空间) XDATA (外部数据存储空间) BIT (内部RAM低地址区的可位寻址的空间) CODE (程序存储器空间) 可选的再定位类型定义了L51连接时的定位方式,再定位类型: UNIT:定义一个可开始于任一单元的段对于BIT型的段,一个单元是一个位, 其它所有的段一个单元是一个字节. PAGE:定义一个起始地址必须是256的整数倍的段,段的绝对地址由L51自己计算,该类型只允许用于XDATA和CODE类型段. INPAGE:定义一个由L51连接后必须包含在256B的块中,只适用于XDATA和CODE段. INBLOCK:定义一个L51连接后必须包含在2KB中的段,只适用于CODE段. OVERLAYABLE:定义一个可与其他段交叠的覆盖段,其段名符号必须按C51或者PL/M51的规则命名.C51把局部数据段和局部位段定义成?DT?FUNCTIONNAME?MODULENAME 和?BI?FUNCTIONNAME?MODULENAME这是在small模式下.其他的模式略有不同。BITADDRESSABLE:定义一个L51连接后位于可位寻址的区,段长不能超过16B. 2) EQU 格式: 符号名 EQU 表达式 符号名 EQU 寄存器名 EQU伪指令定义一表示数值或寄存器的符号,该符号可用于表达式或助记符指令的操作数,EQU指令定义的符号不能被改变或重新定义,其段类型取决于表达式中的操作数类型类型,无类型的EQU符号可用于任何表达式中. LIMIT EQU 200 VALUE EQU LIMIT-100+’A’

PLC常用指令(很全的)

一、顺控指令 1 触点指令 00 LD 逻辑操作开始 01 LDI 逻辑非操作开始 02 AND 逻辑乘 03 ANI 逻辑乘非 04 OR 逻辑加 05 ORI 逻辑加非 2 连接指令 06 ANB AND逻辑块与 07 ORB OR逻辑块或 08 MPS 存储操作结果 09 MRD 从MPS读取操作结果 10 MPP 从MPS读取操作结果并清除结果 3 输出指令 11 OUT 软元件输出 12 SET 软元件置位 13 RST 软元件复位14 PLS 在输入信号的上升沿 15 PLF 在输入信号的下降沿 16 CHK 软元件输出翻转 4 移位指令 17 SFT 元件移1位 18 SFTP 元件移1位 5 主控指令 19 MC 主控开始 20 MCR 主控复位 6 结束指令 21 FEND 结束主程序 22 END 总的程序末尾, 返回第0步 7 其它指令 23 STOP 停止 24 NOP 空操作 二基本指令 1 比较指令 16位数据比较 25 LD= 当S1=S2, 接通, 当S1≠S2, 断开 26 AND= 27 OR= 28 LD<> 当S1≠S2, 接通, 当S1=S2, 断开 29 AND<> 30 OR<> 31 LD> 当S1>S2, 接通, 当S1≤S2, 断开 32 AND> 33 OR> 34 LD<= 当S1≤S2, 接通, 当S1>S2, 断开 35 AND<= 36 OR<= 37 LD< 当S1= 当S1≥S2, 接通, 当S1= 42 OR>= 32位数据比较 43 LDD= 当(S1+1,S1)=(S2+1,S2), 接 通 44 ANDD= 45 ORD= 46 LDD<> 当(S1+1,S1)≠(S2+1,S2),接 通 47 ANDD<> 48 ORD<> 49 LDD> 当(S1+1,S1)>(S2+1,S2), 接 通 50 ANDD> 51 ORD> 52 LDD<= 当(S1+1,S1)≤(S2+1,S2),接 通 53 ANDD<= 54 ORD<=

实验二 伪指令实验

实验二伪指令实验 一、实验目的 1.掌握数据定义伪指令的使用方法; 2.掌握符号定义伪指令的使用方法; 3.掌握段定义伪指令的使用方法 4.掌握各种数据在内存中的存放形式。 二、实验要求 1.学会使用数据定义伪指令定义字节数据、字数据、双字数据、四字数据及十字数据; 2.学会使用DEBUG中的D命令观察字节数据、字数据、双字数据等在内存中的存放格式; 3.学会使用DEBUG中的D命令观察带符号数据和不带符号数据在内存中的存放形式; 4.学会使用DEBUG中的D命令观察实数在内存中的存放形式。 三、实验举例 【例3.2】 编辑、汇编、连接下列程序段,然后在DEBUG下观察数据的存储格式。 【步骤一】 启动EDIT编辑器,编辑源程序。 程序清单如下: CSEG SEGMENT X1 DB 0AH,0BH,0CH,0DH,31H,32H,33H,34H X2 DB 10,11,12,13,14,15,16,17,18 X3 DB -1,-2,-3,-4,-5,-6,-7,-8 Y1 DB 25+25,78-34,15*4,90/3 Y2 DB 80 MOD 9,3 DUP(50) Y3 DB ‘ABCDEFGH’ Z1 DW 1234H,5678H,0ABCDH,0ABEFH Z2 DW -1,-2,-3,-4,-5,-6,-7,-8 Z3 DW OFFSET Y3,3 DUP(0),OFFSET Z2,3 DUP(?) CSEG ENDS END 程序输入完毕,以EXAM2.ASM为文件名存入磁盘,进行下一步操作。 【步骤二】 对源程序EXAM2.ASM进行汇编,生成目标程序EXAM2.OBJ。 操作如下: C:>\MASM EXAM2;↙ 屏幕显示如下信息: Microsoft (R) Macro Assembler Version 5.00 Copyright (C) Microsoft Corp 1981-1985, 1987. All rights reserved. 50554 + 449926 Bytes symbol space free 0 Warning Errors 0 Severe Errors 汇编通过,没有错误信息产生,进行下一步操作。 【步骤三】 对目标程序EXAM2.OBJ进行连接,生成执行程序EXAM2.EXE。 操作如下: C:>\LINK EXAM2;↙ 屏幕显示如下信息:

8086伪指令

8086伪指令(汇编语言程序格式) 汇编语言程序中的语句可以由指令、伪指令和宏指令组成。上一章我们介绍了8086指令系统中的6类指令,每一条指令都对应一种CPU操作。 伪指令又称为伪操作,它是在对源程序汇编期间由汇编程序处理的操作,它们可以完成如处理器选择、定义程序模式、定义数据、分配存储区、指示程序结束等功能。 宏指令是由用户按照宏定义格式编写的一段程序,其中语句可以是指令、伪指令,甚至是已定义的宏指令。宏指令将在第七章中介绍。 伪指令和指令的区别在于,每一条指令必须生成机器代码,然后在程序运行期间由CPU来执行其操作;而伪指令是在汇编期间由汇编程序执行的操作命令,除了数据定义及存储器分配伪指令分配存储器空间外,其它伪指令不生成目标码。和各种指令一样,伪指令也是程序设计不可缺少的工具。下面介绍一些常用的伪指令。 4.2.1 段定义伪指令 段定义伪指令是表示一个段开始和结束的命令,80x86有两种段定义的方式:完整段定义和简化段定义,分别使用不同的段定义伪指令来表示各种段。 4.2.1.1 完整的段定义伪指令 完整段定义伪指令的格式如下: 段名 SEGMENT . . . 段名 ENDS 段名由用户命名。对于数据段、附加段和堆栈段来说,段内一般是存储单元的定义、分配等伪指令语句;对于代码段中则主要是指令及伪指令语句。 定义了段还必须说明哪个段是代码段,哪个段是数据段。ASSUME伪指令就是建立段和段寄存器关系的伪指令,其格式为: ASSUME 段寄存器名: 段名,… 段寄存器名必须是CS、DS、ES和SS中的一个,而段名必须是由SEGMENT定义的段名。 ·定位类型:说明段的起始边界值(物理地址)。 ·组合类型:说明程序连接时的段组合方法。 ·类别:在单引号中给出连接时组成段组的类型名。连接程序可把相同类别的段的位置靠在一起。 例4.1 ; * * * * * * * * * * * * * * * * * * * * * * * data_seg1 segment ; 定义数据段 . .

第4章 伪指令与源程序格式

第4章伪指令与源程序格式 汇编语言程序的语句有三种,即指令、伪指令,还可以有宏指令。关于宏指令将在第7章介绍,本章介绍部分常用的伪指令(又称伪操作)。这些伪指令在程序中是必不可少的,主要用来定义数据变量和程序结构。本章还介绍指令中的操作数和运算符,通过本章的学习,可以学会使用简便而有效率的指令格式,正确定义数据变量,熟知源程序的格式,编写完整的汇编语言程序。 4.1 伪指令 伪指令和指令不同的是,指令是在程序运行期间由计算机的CPU来执行的,而伪指令是在汇编程序对源程序进行汇编期间由汇编程序处理的操作。它们可以完成如定义数据、定义程序模式、分配存储区、指示程序结束、处理器选择等功能。这里只介绍一些常用的伪指令。有些和宏汇编有关的伪指令在介绍宏汇编时再作说明。 4.1.1 处理机选择伪指令 由于80x86的所有处理器都支持8086指令系统,但每一种高档的机型又都增加了一些新的指令。为了能使用这些新增指令,在编写程序时要用处理机选择伪指令对所用的处理机作出选择,也就是说,要告诉汇编程序应该选择哪一种指令系统。 处理机选择伪指令有以下几种: .8086 选择8086指令系统 .286 选择8O286指令系统 .286P 选择保护方式下的80286指令系统 .386 选择80386指令系统 .386P 选择保护方式下的8O386指令系统 .486 选择80486指令系统 .486P 选择保护方式下的8O486指令系统 .586 选择Pentium指令系统 .586P 选择保护方式下的Pentium指令系统 指令中的点‘.’是需要的。这类伪指令一般放在整个程序的最前面。如不给出,则汇编程序认为其默认选择是8086指令系统。 4.1.2 段定义伪指令 我们结合第2章已介绍的程序实例2来看段定义,注意有分号的注释行,程序如下:例4.1 data segment ;定义数据段data string db ‘hello,world!$’ data ends code segment ;定义代码段code assume cs:code,ds:data ;指定段寄存器和段的关系 start:mov ax,data ;对ds赋data段基地址 mov ds,ax mov dx,offset string mov ah,9 int 21h mov ah,4ch

ARM汇编伪指令宏的用法详解_MACRO-MEND_.

ARM 汇编伪指令宏的用法详解(MACRO-MEND 宏是一段独立的程序代码,它是通过伪指令定义的,在程序中使用宏指令即可调用宏。当程序被汇编时,汇编程序将对每个调用进行展开,用宏定义取代源程序中的宏指令。 MACRO 、MEND 语法格式: MACRO [$ label] macroname{ $ parameter1, $ parameter,…… } 指令序列 MEND MACRO 伪操作标识宏定义的开始,MEND 标识宏定义的结束。用MACRO 及MEND 定义一段代码,称为宏定义体,这样在程序中就可以通过宏指令多次调用该代码段。 其中, $ label在宏指令被展开时,label 会被替换成相应的符号,通常是一个标号。在一个符号前使用$表示程序被汇编时将使用相应的值来替代$后的符号。 macroname 为所定义的宏的名称。 $parameter为宏指令的参数。当宏指令被展开时将被替换成相应的值,类似于函数中的形式参数,可以在宏定义时为参数指定相应的默认值。 宏指令的使用方式和功能与子程序有些相似,子程序可以提供模块化的程序设计、节省存储空间并提高运行速度。但在使用子程序结构时需要保护现场,从而增加了系统的开销,因此,在代码较短且需要传递的参数较多时,可以使用宏汇编技术。首先使用MACRO 和MEND 等伪操作定义宏。包含在 MACRO 和 MEND 之

间的代码段称为宏定义体,在MACRO 伪操作之后的一行声明宏的原型(包含宏名、所需的参数),然后就可以在汇编程序中通过宏名来调用它。在源程序被汇编时,汇编器将宏调用展开,用宏定义体代替源程序中的宏定义的名称,并用实际参数值代替宏定义时的形式参数。 宏定义中的$label是一个可选参数。当宏定义体中用到多个标号时,可以使用类似$label.$internallabel的标号命名规则使程序易读。 MACRO 、 MEND 伪操作可以嵌套使用。 使用示例: MACRO $HandlerLabel HANDLER $HandleLabel ;宏的名称为HANDLER ,有1个参数$HandleLabel $HandlerLabel sub sp,sp,#4 stmfd sp!,{r0} ;decrement sp(to store jump address ;PUSH the work register to stack(lr does not push because it return to original address ;load the address of HandleXXX to r0 ;load the contents(service routine start address of HandleXXX ;store the contents(ISR of HandleXXX to stack ;POP the work register and pc(jump to ISR ldr r0,=$HandleLabel ldr r0,[r0] str r0,[sp,#4] ldmfd sp!,{r0,pc} MEND ;在程序中调用该宏

PIC16系列_单片机常用伪指令(汇编)

PIC 单片机端口电平变化中断使用必须注意的问题 PICC18使用说明 PIC 单片机常用伪指令 PIC单片机2009-02-19 11:16:40 阅读8 评论0 字号:大中小订阅 3.2.3 MPASM 的伪指令 我们在第一章中已经详细介绍了中档PIC 单片机的35 条指令,源程序的编写主要就是用这些基本的指令实现你的控制任务。但为了增加源程序的可读性和可维护性,我们引入了伪指令的概念。伪指令本身不会产生可执行的汇编指令,但它们可以帮组“管理”你编写的程序,其实用性和必要性绝不亚于35 条正真的汇编指令。我们在此着重介绍最常用的几种 伪指令。 #include 或include #include 伪指令的作用是把另外一个文件的内容全部包含复制到本伪指令所在的位置。 被包含复制的文件可以是任何形式的文本文件,当然文件中的内容和语法结构必须是MPASM 能够识别的。最经常被“include”的是针对PIC 单片机内部特殊功能寄存器定义的包含头文件,在MPLAB 安装后它们全部放在路径“ C:\Program Files\MPLAB IDE\MCHIP_Tools”下,每一个型号的PIC 单片机都有一个对应的预定义包含头文件,扩展名是“.inc”。除了一些符号预定义文件,你也可以把现有的其它程序文件作为一个代码模块直接“包含”进来作为自己程序的一部分。见例3-01。 #include ;把预定义的PIC16F877A 寄存器符号包含到此处 #include ”math.asm” ;把现有的程序文件包含进来作为自己代码的一部分 例3-01 请注意被包含文件的引用方式。一种是<>尖括号引用,这种引用意味着让编译器去默认的路径下寻找该文件,MPASM 默认的寄存器预定义文件存放路径即为上面提及的MPLAB 安装后的目录;另一种是””双引号引用,这种引用方式的意思是指示编译器从引号中指定的全程文件路径下寻找该文件。例3-01 中”math.asm”没有指定路径,即意味着在当前项目路径下寻找math.asm 文件。如果编译器找不到被包含的文件,将会有错误信息告 知。 请在你的源程序中尽量用MPLAB 标准头文件定义的寄存器符号。一来这些被定义的寄存器符号和芯片数据手册上的描述一一对应,理解起来即直观又容易;二来如果用你自己定义符号就缺乏一个大家能一起交流的标准平台,其他人要解读你的代码时将费时费力。故例3-01 中的首行#include 包含引用伪指令可以说是PIC 单片机程序编写时的标准必备。

ARM常用的伪指令

在线学习好工作https://www.doczj.com/doc/ed16110507.html,/ ARM常用的伪指令 AREA就是常见的伪指令之一。AREA是声明区域段,数据区,代码区等等。什么是数据段呢?数据段是来定义数据结构体的。格式是AREA test,CODE,READONLY。还有指令CODE16、CODE32,格式就直接写上就是。目的是声明以下是32位还是16位指令,注意不是切换arm和thunmb模式。如果是16位,那就是thunmb指令。 操作:这是之前的,如果在这里做一个声明,CODE32,也就是表示ARM指令。如果这里CODE16,就表示一下代码是16位指令,也就是thunmb指令, 也就是说在编译的时候会按照thunmb指令来进行汇编。大家注意一点,在这里通过这个切换,并不会改变处理器的运行的处理模式。不会把ARM指令状态切换为thunmb指令状态。这个切换是在状态寄存器里面去切换T。这个地方只是告诉汇编器而已,所以并不会更换运行时候的指令切换方式。 entry:entry伪指令用于指定汇编程序的入口点。在一个完整的汇编程序中至少要一个entry(也可以多个,当有多个entry时,程序的真正入口点由链接器指定),但在一源文件里最多只能有一个entry(可以没有)。 END:END伪指令用于通知编译器已经到了源程序的结尾。 EQU:EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于c语言的#define。格式是UARTLCON0EQU.0x3FFD00。比方说:SUNDYCON1

EQU0x3200000,我们定义了一个常量,这个常量可以拿来直接用。这里注意一点,我们编译先看一下。这里就出错了。 未知的操作代码。这是怎么回事?汇编这一块,跟自己的汇编器,编译器是有关系的,有时跟ID的环境都有关。在ARM里面,特别ADS里面,他对是否顶头,和Tab要求非常严格。因为我们这里不是一个标准指令,它会看第一个是什么操作码,这里操作码是不识别的,所以这里就出错认不出来。这是应该怎样做呢?首先把SUNDY顶头,就可以知道只是个伪指令。 EXPOET:export伪指令用于程序中声明一个全局的标号,该标号可在其他的文件中引用。export可用GLOBAL代替。标号在程序中区分大小写,weak选项声明其他的同名标号优先于该标号被引用。 IMPORT相当于静态引用。IMPORT伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,而且无论当前源文件是否引用该标号,该标号都会被加入到当前源文件的符号表中。 EXTERN相当于动态引用。EXTERN伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前的源文件中引用,如果当前源文件实际未引用该标号,该标号就不会被加到当前源文件的符号表中。 GET相当于引用文件。GET伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。可以使用INCLUDE代替GET。 RN:RN伪指令用于给一个寄存器定义一个别名。采用这种方式可以方便程序员记忆该寄存器的功能。其中,名称为给寄存器定义的别名,表达式为寄存器的编码。

指令周期机器周期等各种周期介绍

时钟周期: 时钟周期也称为振荡周期,定义为时钟脉冲的倒数(可以这样来理解,时钟周期就是单片机外接晶振的倒数,例如12M的晶振,它的时间周期就是1/12 us),是计算机中最基本的、最小的时间单位。 在一个时钟周期内,CPU仅完成一个最基本的动作。对于某种单片机,若采用了1MHZ的时钟频率,则时钟周期为1us;若采用4MHZ的时钟频率,则时钟周期为250us。由于时钟脉冲是计算机的基本工作脉冲,它控制着计算机的工作节奏(使计算机的每一步都统一到它的步调上来)。显然,对同一种机型的计算机,时钟频率越高,计算机的工作速度就越快。 8051单片机把一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示)。 机器周期: 在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段,每一阶段完成一项工作。例如,取指令、存储器读、存储器写等,这每一项工作称为一个基本操作。完成一个基本操作所需要的时间称为机器周期。一般情况下,一个机器周期由若干个S周期(状态周期)组成。 8051系列单片机的一个机器周期同6个S周期(状态周期)组成。前面已说过一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示),8051单片机的机器周期由6个状态周期组成,也就是说一个机器周期=6个状态周期=12个时钟周期。 例如外接24M晶振的单片机,他的一个机器周期=12/24M 秒; 指令周期: 执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期也不同。 对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。 通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。 总线周期: 由于存贮器和I/O端口是挂接在总线上的,CPU对存贮器和I/O接口的访问,是通过总线实现的。通常把CPU通过总线对微处理器外部(存贮器或I/O接口)进行一次访问所需时间称为一个总线周期。 总结一下,时钟周期是最小单位,机器周期需要1个或多个时钟周期,指令周期需要1个或多个机器周期;机器周期指的是完成一个基本操作的时间,这个基本操作有时可能包含总线读写,因而包含总线周期,但是有时可能与总线读写无关,所以,并无明确的相互包含的关系。

相关主题
文本预览
相关文档 最新文档