2023/9/27 -- ARM

[Assembly language related syntax]

1. Components of assembly language

1.伪操作:不参与程序的执行,但是用于告诉编译器程序该怎么编译
.text 
.global  .end   .if  .else  .endif  .data

2.汇编指令
编译器将一条汇编指令编译成一条机器码,在内存里一条指令占4字节内存,一条指令可以实现一个特定的功能

3.伪指令
不是指令,看起来像是一条指令,可以实现和指令类似的功能。一条伪指令实际上可能是由多条指令共同实现

4.注释
单行注释:   @
多行注释   /*  */
条件编译
     .if 0
       指令段
      .else
        指令段
      .endif

2. Introduction to assembly instructions

1.基本数据操作指令
    数据搬移指令   =
    数据移位指令   << >>  
    数据算数运算指令   + - * /
    位运算指令    &   | ~  ^
    数据比较指令
2.跳转指令
3.内存读写指令
4.状态寄存器读写指令
5.软中断指令

3. Basic syntax format of assembly instructions

    指令的基本格式:
<opcode>{<cond>}{s}  <Rd>,  <Rn>,  <shifter_operand>
    解释:
    
<opcode>:指令码
     {<cond>}:条件码
     {s}:状态位,如果在指令后面加上s,则运算的结果会影响CPSR的条件位
     <Rd>:目标寄存器
     <Rn>:第一操作寄存器  只能是寄存器
     <shifter_operand>:第二操作数,可以是寄存器,也可以是立即数
  按照指令码将第一操作寄存器和第二操作数进行运算,将运算后的结果保存在目标寄存器
  
注意:      
1.一条汇编指令一般占一行
2.汇编不区分大写小写                         

【Assembly instructions】

1. Data movement instructions

1.1 Format

<opcode>{<cond>}{s}  <Rd>,  <shifter_operand>
解释:
    
<opcode>:指令码
     {<cond>}:条件码
     {s}:状态位,如果在指令后面加上s,则运算的结果会影响CPSR的条件位
     <Rd>:目标寄存器
     <shifter_operand>:第一操作数,可以是寄存器,也可以是立即数
  按照指令码将第一操作数运算后的结果保存在目标寄存器
  
指令码功能:
    mov:将第一操作数的值保存在目标寄存器
    mvn:将第一操作数的值按位取反,将结果保存在目标寄存器

1.2 Example

1.3 The concept of immediate data

Definition: The data that can be directly used as part of the instruction to participate in the execution of the instruction is the immediate value. The immediate value is obtained by circularly shifting a number in the range of 0-255 to the right by an even number of bits.

The lower 12 bits are reserved in 32 bits of the instruction to store the immediate data.

如何判断一个数据是不是立即数:
  在0-255范围内找一个数,让它循环右移偶数位(一个0-15范围内的数*2得到),如果能够得到这个数据,则这个数就是一个立即数。
  循环右移:最低位移出去的数补到最高位
  0000 0000 0000 0000 0000 0000 0000 1010 
  右移两位: 0000 0000 0000 0000 0000 0000 0000 0010
  循环右移两位: 100000 0000 0000 0000 0000 0000 0000 10
  ex:
  0X104: 0000 0000 0000 0000 0000 0001 0000 0100
      循环右移2位-》000000 0000 0000 0000 000000 0100 0001   -》0x41
      换句话说,将0x41循环右移30位得到0X104,所以,0X104是一个立即数
0X101:0000 0000 0000 0000 0000 0001 0000 0001
0X101找不到一个0-255范围内的数循环右移得到它,所以0X101不是立即数

1.4 Save non-immediate values ​​to registers

伪指令:
    LDR 目标寄存器,=数值
    将指定的数据放在目标寄存器中
    
ex:LDR r1,=0X12345678

2. Shift instructions

2.1 Format and command code

格式:<opcode>{<cond>}{s}  <Rd>,  <Rn>,  <shifter_operand>
解释:将第一操作寄存器的数值移位第二操作数指定的位数,将结果保存在目标寄存器中

指令码:
LSL:左移运算  低位补0
LSR:右移运算   高位补0
ROR:循环右移:低位移出的值补到高位

2.2 Example

1.左移
        mov r0,#0XFF
    lsl r1,r0,#0X4  @将R0的值左移4位保存在r1寄存器  R1结果:0XFF0
 2.右移
 mov r0,#0XFF
lsr r1,r0,#0X4  @将R0的值右移4位保存在r1寄存器  R1结果:0XF
3.循环右移
mov r0,#0XFF
ror r1,r0,#0X4  @将R0的值循环右移4位保存在r1寄存器  R1结果:0XF000000F
4.c风格写法
mov r0,#0XFF
ror r1,r0,#(0X1<<2)  @将R0的值循环右移4位保存在r1寄存器  R1结果:0XF000000F

3. Bit operation instructions

3.1 Format and function code

格式:<opcode>{<cond>}{s}  <Rd>,  <Rn>,  <shifter_operand>
解释:将第一操作寄存器和第二操作数进行位运算,将结果保存在目标寄存器中

指令码:
    and:与 与0清0 与1不变
    orr:或  或1置1 或0不变
    eor:异或  相同为0 不同为1
    bic:按位清零指令,想将哪一位设置为0,只需要用bic指令给这一位运算一个1即可

3.2 Example

1.and:
mov r0,#0XFF
    and r1,r0,#0XF0  @R1结果为0XF0
 2.ORR:
     mov r0,#0XFF
    orr r1,r0,#0XF000  @R1结果为0XF0FF
3.EOR:
    ldr r0,=0xf0f0
    EOr r1,r0,#0XFF  @R1结果为0XF00F
0000 0000 0000 0000 0000 0000 1111 1111
0000 0000 0000 0000 1111 0000 1111 0000
结果:0000 0000 0000 0000 1111 0000 0000 1111 -》0XF00F

4.BIC
 ldr r0,=0xFF
    BIC r0,r0,#(0x1<<5)  @将R0的值第5位清0 @R0结果为0XDF

3.3 Exercise

LDR r1,=0X12345678  @将0X12345678存放在r1寄存器
0001 0010 0011 0100 0101 0110 0111 1000
1.将R1寄存器的第4位清0,其他位不变
        and r1,r1,#(~(0X1<<4))
    或者BIC R1,R1,#(0x1<<4)
2.将r1寄存器第7位置1,其他位不变
orr r1,r1,#(0X1<<7)
3.将r1寄存器[31:28]清0,其他位不变
and r1,r1,#(~(0Xf<<28))
    或者BIC R1,R1,#(0xF<<28)
4.将r1寄存器[7:4]置1,其他位不变
orr r1,r1,#(0XF<<4)
5.将r1寄存器[15:11]设置为10101,其他位不变 
    @先清0
    BIC R1,R1,#(0X1F<<11)
    @再置位
    orr r1,r1,#(0X15<<11)

4. Arithmetic operation instructions

4.1 Format and command code

格式:<opcode>{<cond>}{s}  <Rd>,  <Rn>,  <shifter_operand>
解释:将第一操作寄存器的值和第二操作数进行算数运算,结果保存在目标寄存器中

add:加法运算
adc:进行加法运算时需要考虑CPSR的条件位
sub:减法运算
sbc:进行减法运算时需要考虑CPSR的条件位
mul:乘法运算

4.2 Example

1.ADD:加法
  ex1:  mov r1,#1
      mov r2,#2
     add r3,r1,r2@r3=r1+r2
  ex:
      mov r1,#0XFFFFFFFE
    mov r2,#2
    addS r3,r1,r2@r3=r1+r2  @运算的结果影响到条件位
2.SUB
        mov r1,#0XFFFFFFFE
    mov r2,#2
    sub r3,r1,r2@r3=r1-r2
 ex2:
         mov r1,#0XFFFFFFFE
    mov r2,#2
    subs r3,r2,r1@r3=r2-r1 
3.ADC
mov r1,#0XFFFFFFFE
mov r2,#2
    ADDS r3,r2,r1 @r3=r1+r2 
    ADC R4,R2,#3  @R4=R2+3+cpsr(C位)  6 
 
4.sbc:减法运算考虑条件位
mov r1,#0XFFFFFFFE
    mov r2,#2
      SUBS r3,r2,r1 @r3=R2-R1    4
    sbC R4,R1,#3  @R4=R1-3-CPSR(C位取反)

4.3 Arithmetic operations on 64-bit data

原则:
一个 64位数保存在两个寄存器
高32位运算,低32位运算
     mov r1,#0XFFFFFFFE  @保存第一个数据的低32位
    mov r2,#2@保存第一个数据的高32位
    mov r3,#3 @保存第二个数据的低32位
    mov r4,#4 @保存第2数据的高32位
    @低32位运算要求影响条件位
    ADDS R5,R1,R3@R5保存运算后结果的低32位
    ADC R6,R2,R4@R6寄存器保存运算结果的高32位,需要考虑条件位
    

5. Compare instructions

格式:
    cmp 第一操作数,第二操作寄存器
    比较两个数据
cmp命令本质:实际上就是比较的两个数进行减法运算,并且减法运算的结果会影响到CPSR寄存器的条件位
通常比较指令完毕之后会使用条件码进行判断,根据判断的结果做不同的逻辑
    

condition code

Add the mnemonic suffix of the condition code after an instruction. If the conditions corresponding to the condition code are met, we will perform the corresponding instruction operation, otherwise no operation will be performed.

mov r1,#3
        mov r2,#4
        cmp r1,r2  @比较两个数
        SUBHI r3,r1,r2  @如果r1>r2 进行减法运算
        MULEQ r3,r1,r2@如果两数相等,进行乘法运算
        ADDCC R3,R1,R2@如果r1<r2  ,进行加法运算

6. Jump instructions

格式:
<opcode>{<cond>} 标签
功能:跳转到指定的标签下

指令码:
b:跳转时不影响LR寄存器的值

ex:.text
.global  _start
    
_start:
        mov r1,#3
        mov r2,#4
        b fun1 @程序跳转
        mul r5,r1,r2
    
stop:
    b stop  

fun1:
    add r4,r1,r2

    
    
.end
    

bl:跳转时影响LR寄存器的值

.text
.global  _start
    
_start:
        mov r1,#3
        mov r2,#4
        bl fun1 @程序跳转
        mul r5,r1,r2
    
stop:
    b stop  

fun1:
    add r4,r1,r2
    mov pc,lr @程序返回

    
    
.end
    

【Task】

Realize the accumulation of 1-100

.text
.globl _start

_start:  
	MOV R0,#0
	MOV R1,#1
	MOV R2,#100
	
FUN:	
	CMP R1,R2
	ADDNE R0,R0,R1
	ADDNE R1,R1,#1
	BNE FUN		
	
stop:
	b stop
.end
	

Guess you like

Origin blog.csdn.net/weixin_54147737/article/details/133362201