ARM------->第二天,汇编指令

1.什么是汇编指令

汇编指令:是机器指令的助记符,经过编译后会得到一串01010组成的机器码,可以由cpu读取执行

伪指令:本质上不是指令,只是和指令一起写在代码中,是指导编译过程的,是编译系统提供的,不会生成对应的机器码

2.数据搬移指令(指令格式)

mov r0, #1   @将立即数1赋值给r0

mov r1,r0    @将r0的值赋值给r1

mov r2, r0, lsl #1   @将r0的值左移1位赋值给r2

mov r3, r2, lsr #2   @将r2的值右移两位赋值给r3

mvn r5,r3   @将r3取反之后赋值给r5

.text    @定义一个指令段

mov r0,#3
mov r1,r0

mov r2, r1, lsl #2	
mov r3,r2,lsr #1	

mvn r5,#0	

.end    @表示汇编程序结束

汇编指令的格式:

<opcode> {<cond>} {s} <rd>, <rn>,{<operand2>}

其中:<>是必须的

            {}是可选的

opcode:汇编指令

cond:执行条件

s:是否影响cpsr寄存器的值(cpsr的条件位)

rd:目标寄存器

rn:第一操作数寄存器,只能是寄存器

operand2:第二操作数

以mov指令为例,学习机器指令格式: 

mov {cond} {s} rd, op2

31-28   27  26  25   24-21  20  19-16  15-12  11-0

[31-28]:条件码

27-26:预留  默认为0

25: 1----->第二操作数是立即数  0----->第二操作数是寄存器

24-21:操作码   mov------>1101

20:1------>影响cpsr的值   0------>不影响cpsr的值

19-16:第一操作数寄存器

15-12:目标寄存器

11-0:第二操作数寄存器

如果是立即数:0-7位  立即数

                         11-8:移位值

最终的立即数 = 立即数 循环右移 (移位值*2)位

合法立即数:如果一个32位的数,可以通过0-7位的数循环右移偶数位得到就是合法的

0x00ab0000(合法)   0x0000ffff (不合法)  0x10000001(合法)

E3A00001

1110  001 1101 0  0000 0000 0000 0000 0001

总结:如果立即数是0-255,绝对是合法的,可以直接使用mov指令,而如果大于255,就直接使用ldr伪指令就好

三级流水线:取指  译码  执行

pc:正在取指的指令的地址

正在执行的指令的地址 = pc-8

3.算术指令

add r0,r1,r2   @r0 = r1+r2

add r0,r1   @r0+=r1

sub @减法

mul  @乘法

.text

mov r0, #1
mov r1, r0

add r2,r0,r1

sub r3,r2,#1

mul r5,r2,r3

.end

4.逻辑指令

and r0, r1, r2   @r0 = r1 & r2

orr r0,r1,r2   @r0 = r1 | r2

bic r0, 0xff    @将r0的0-7位清0

.text

mov r0, #0xff
mov r1, #0xef

and r2,r0,r1
orr r3, r0, r1

bic r2, #0x2

.end

5.比较指令

cmp r0,r1   @比较r0和r1的大小

cmp r0,#1    @比较r0和1的大小

moveq r2,#2   @当r0==1的时候,将2赋值给r2

tst r0,#0x2  @测试r0的第2位(从1算的)是否为0

moveq r2,#0xdd

movne r2,#0xee

注意:cmp和tst会自动引起cpsr值的变化

.text

mov r0,#1
mov r1,r0

cmp r1,#1

moveq r2,#0xff

@tst r0,#0x2

@moveq r2,#0xdd
@movne r2,#0xee

.end

6.跳转指令

b loop  @跳转到loop这个语句标号处

loop:

nop

nop

其中:nop是空指令,只占用时间,不做任何事情

          loop:语句标号,表示的是它下一条指令的地址

实现1-5的累加和

.text

.if 0
mov r0,#1	@i
mov r1,#0	@sum

loop:
	cmp r0,#6
	addlt r1,r0	
	addlt r0,#1	
	blt loop
	nop
	nop
	nop
.endif	

.end

bl:在跳转时,会将返回地址自动保存到lr中

总结:b------->循环  bl------>调用函数

汇编中如何传参?

规定:r0-r3就是参数         r0是返回值

      如果超过四个参数,就入栈

注意:lr = pc-4

.text

main:
	nop
	nop
	nop
	mov r0,#1
	mov r1,#5
	nop
	bl addFunc
	nop
	nop
	nop
	
addFunc:
	mov r5,#0	@sum

loop:
		cmp r0,r1	
		addls r5,r0	
		addls r0,#1
		blt loop
		mov r0,r5
addFunc_end:
		mov pc,lr

.end

7.内存访问指令

ldr:将内存的值拷贝到寄存器

str:将寄存器的值拷贝到内存

前提:内存是通过地址访问的

ldr r0,[r1]   @将r1这个地址的内容拷贝给r0,r1存的是一块内存的首地址

                 @r0 = *r1

str r0,[r1]   @*r1 = r0

.text


@将a的值拷贝给c
@将a的值拷贝到寄存器
ldr r1,=a	@伪指令
ldr r2,=c

ldr r0,[r1]	@汇编指令

@将寄存器的值拷贝给c
str r0,[r2]

.data:	@定义一个数据段
@定义变量a和c
a:
	.word 0x12345678    @在存储器中分配4个字节的内存单元,与int一样
c:
	.word 0x0

.end

ldr和str:四个字节

ldrb和strb: 一个字节

ldrh和strh:两个字节

拷贝字符串:

一次拷贝一个字符

ldr r0,[r1, #4]  @r0 = *(r1+4)

ldr r0,[r1],#4   @r0=*r1, r1+=4

.text

@将str1的值拷贝给str2
ldr r1,=str1
ldr r2,=str2

loop:
	ldrb r0,[r1],#1
	cmp r0,#0
	beq done
	strb r0,[r2],#1
	b loop

done:
	nop
	nop
	nop

.data
str1:
	.string "abcde\0"	@定义字符串
str2:
	.space 10	@申请10个字节空间
	
.end

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值