ARM汇编语言了解

目录

基础知识

ARM汇编:

数据操作指令

mov指令

mvn指令:取反

伪指令

移位运算解释

位操作指令

测试指令

指令的条件执行

程序跳转(函数调用)

不带返回链接的跳转

 带返回的跳转  在跳转动作执行时,会将PC备份到LR中

学习目的:了解硬件指令执行逻辑,知道c语言如何编译和运行的,了解汇编指令中的专业术语

基础知识

汇编文件格式:

.text //代码段的开始

@代码指令

//代码存储区(只读)

.data  //数据段

@ 数据存储区  可读可写

.end //结束

  • 汇编中的符号:
    1. 标识符:本身不会生成指令,只是一些标志
    2. 汇编指令:每一条汇编指令,都可以编译为与之对应的一个机器码
    3. 伪指令:该指令编译后可能生成的机器指令不只一个
  • 汇编指令结构:

指令码   <目标寄存器>,<第一操作寄存器>,<第二操作寄存器或 立即数 移位>

mov  r0,#1

  • ARMcpu使用的ARM指令集是一种精简处理器指令集(RISC)

它保留了简单的、使用频率高的指令,追求结构简单,成本低功耗低

  • X86使用的是复杂处理器指令集(CISC),追求的是高效率,很多复杂的动作都有指令与之对应
  • ARM指令集指令定长,每个指令固定长度为4字节;而复杂处理器指令集(CISC)是变长指令集,1-16字节,仅有的几个指令可以条件执行
  • 一条ARM指令的 指令码 构成:

4bit 条件码   4bit 指令码   4bit 目标寄存器编号   4bit 第一操作寄存器编号  12bit 第二操作寄存编号或立即数或寄存器移位

ARM汇编:

数据操作指令

mov指令

格式:mov 目标寄存器(R0-R15),立即数或寄存器移位

立即数概念:为了解决在12bit空间内,能够覆盖更广的数值空间

立即数即一个8bit的数,循环右移偶数位,能够得到的数,就是立即数

测试练习:  判断下列哪些是立即数

0x123  不是

0b0001 0010 0011

0x188000  是

0b 0001 1000 1000 0000 0000 0000

0x7080    不是

0b 0111 0000 1000 0000

mvn指令:取反

伪指令

将非立即数想办法变成立即数

例如:ldr r0,=0x12345678    ‘=’表示立即数,‘ldr'表示伪指令

移位运算解释

<<   逻辑左移    高位移出丢弃 低位补0

>>   逻辑右移    低位移出丢弃 高位补0

算数左移    高位移出丢弃 低位补0

 算数右移    低位移出丢弃 高位补符号位

  1.  算数运算

    1. add +

    2. SUB:-  

    3. sbc:带错位的减法

    4. rsb:逆向减法

    5. rsc:带错位的逆向减法

    6. mul:乘法

    adc 带进位的加法,主要用于高于32位数的加法
  2. ARM中的除法:

软件除法: 将除法运算 通过 其他运算实现 - >> <<

硬件除法: FPU 浮点运算单元

  1. 位操作指令

    1. bic--位清除操作:
    2. C中逻辑:  &&  ||   ! 
  2. C中位  :  &    |     ~     ^ 
  3. 汇编:    and  orr   mvn   eor

& 按位与:   与0得0 与1不变      对某些bit进行置0操作  或 保留某些bit的值

| 按位或:   或1得1 或0不变      对某些bit进行置1操作

^ 按位亦或: 相同得0 不同得1     对某些bit进行取反操作

测试指令

  1. tst--位测试指令,其结果直接影响cpsr,不产生放到目的寄存器的结果,属于比较指令
  2. teq--相等测试
  3. cmp--大小测试指令

指令的条件执行

  1. 内存读写操作指令

单寄存器操作:  一次性从内存中读写 一个寄存器(4个字节)数据  地址必须要4字节对齐

LDR:  从内存中 读取一个数据到 寄存器中

STR:  将寄存器中的一个数据 写入 到内存中

ldrh  从内存中 读取一个short数据到 寄存器中

strh   将寄存器中的一个short(最低16bit)数据 写入 到内存中

ldrb  从内存中 读取一个字节数据到 寄存器中

strb  将寄存器中的一个字节(最低8bit)数据 写入 到内存中

汇编中 连续操作内存 使用 索引

前索引:      基地址 先 + 偏移量  然后操作这个地址中的数据  不会更改基地址  *(p+1)

后索引:      先操作基地址中的数据, 然后 基地址 += 偏移量   会更改基地址    *p++

自动索引:    基地址 先 += 偏移量 然后操作这个地址中的数据  会 更改基地址   *++p

程序跳转(函数调用)

跳转指令:  本质是 修改PC

 C语言中 goto  while  for  case

不带返回链接的跳转

示例: b stop   // 跳转到stop标记位置

例1:

C switch case

switch(a)  // a =r0  b=r1

{

case 0:

b = 1;

break;

case 1:

b = 2;

case 2:

b = 3;

break;

default:

b = 4;

}
对应汇编

mov         r0,#1   @ a = 1


teq         r0,#0   @ case 0:

moveq   r1,#1   @ b = 1;

beq stop   @ 跳转指令  break;

teqne   r0,#1

moveq   r1,#2

teqne   r0,#2

moveq   r1,#3

beq stop   @ 跳转指令

movne   r1,#4


stop:  @ 地址标记

nop    @ 空指令

例2:

求 1+2+3+.. 100 = ?



int sum = 0;  // r1

int i = 1;    // r0



for(i=1; i<101; i++)        

sum += i;



mov         r0,#1          @ int i = 1

mov         r1,#0          @ int sum = 0



mov         r0,#1          @ for(i=1;

loop:

cmp         r0,#101 @ i < 101

addlt          r1,r0          @ sum += i;

addlt   r0,#1   @ i++;

blt          loop



nop

BL        :  C语言中 函数调用

 带返回的跳转  在跳转动作执行时,会将PC备份到LR中



main()

{

int a = 10,b=20;

int c = func(a,b);

..../



}



int func(a,b)  // a=r0  b=r1

{

static int x = 5;

// 将r4-r12 入栈保存

int i,sum = 0; // i= r2  sum = r3

for(i=a; i<b; i++)        

sum += i;

return sum;  // sum = r0  , 弹栈恢复 r4-r12

}        



//C编译器约定  参数通过 R0-R3传递   超过4个的参数 使用栈传递         

// 函数返回值 通过 R0传递





main:

mov r0,#10  @ 准备参数

mov r1,#20

bl func     @ 调用函数

nop         @ c = r0

nop

50M



@函数 func

func:

mov         r2,r0          @ for(i=a;

loop:

cmp         r2,r1 @ i < b

addlt          r3,r2          @ sum += i;

addlt   r2,#1   @ i++;

blt          loop



mov     r0,r3 @ return sum;

mov     pc,lr



nop



b和bl 的 特性: 本质是 修改PC
b 和 bl  是一个相对于当前PC的一个跳转, 是相对跳转  跳转距离较短

往前或后 跳转  24bit 描述 跳转的范围  

+-  2^23-1 * 4 字节

+-  32M 地址空间  0-4G

长跳转, 直接修改PC 将要跳转的地址 装载到PC中 

Start.s文件示例:


.text
@ldr r0,=0x12345678  @ 伪指令
@mov r0,#1   @ 数据搬移指令 
@mov r1,#2
@add r3,r0,r1


@ 64位+法
@ a = 0x12345678 99999999
@ b = 0x12345678 88888888

@ldr r0,=0x99999999
@ldr r1,=0x88888888
@ldr r2,=0x12345678
@ldr r3,=0x12345678

@adds r4,r0,r1  @ 若有溢出,cpsr 溢出位设置
@adcs  r5,r2,r3  @ r5 = r2+r3 + c;

@mov r0,#5  @ 0b0101
@sub r1,r0,#10  @ r1 = r0-10
@rsb r2,r0,#10  @ r2 = 10-r0

@mul r3,r0,r2

@and r1,r0,#0xfffffffe
@and r1,r0,#-2
@bic  r1,r0,#5

@teq r0,#5

@MoV r0,#5  @ a=5
@mov r1,#6  @ b=6

@cmp r0,r1
@movgt r0,r1   @ a>b a,b是有符号数
@movle r1,r0   @ a<=b a,b是有符号数

/*
switch(a)  // a =r0  b=r1
{
	case 0:
		b = 1;
		break;
	case 1:
		b = 2;
	case 2:
		b = 3;
		break; 
	default:
	b = 4;
}
...

*/
/*
mov 	r0,#1   @ a = 1

teq 	r0,#0   @ case 0:
moveq   r1,#1   @ b = 1;
beq stop   @ 跳转指令  break;
teqne   r0,#1
moveq   r1,#2
teqne   r0,#2
moveq   r1,#3
beq stop   @ 跳转指令
movne   r1,#4

stop:  @ 地址标记
nop    @ 空指令
*/

/*
mov 	r0,#1  	@ int i = 1
mov 	r1,#0  	@ int sum = 0

mov 	r0,#1  	@ for(i=1;
loop:
cmp 	r0,#101 @ i < 101
addlt  	r1,r0  	@ sum += i;
addlt   r0,#1   @ i++;
blt  	loop

*/ 

@ bl 指令 
/*
main:
mov r0,#10  @ 准备参数 
mov r1,#20
bl func     @ 调用函数
nop
nop


@函数 func 
func:
	mov 	r2,r0  	@ for(i=a;
	loop:
	cmp 	r2,r1 @ i < b
	addlt  	r3,r2  	@ sum += i;
	addlt   r2,#1   @ i++;
	blt  	loop

	mov     r0,r3 @ return sum;
	mov     pc,lr
*/
/*
nop

b loop	@ 2
b loop  @ 1
b loop  @ 0   ===>
b loop  @ -1
loop:
b loop  @ -2   pc
b loop  @ -3
b loop  @ -4
b loop

*/

@ 内存操作指令
ldr r0,=a   @ 得到a的地址
ldr r1,[r0] @ r1 = *r0

ldr r2,=m
str r1,[r2] @ *r2 = r1

ldr r3,=name
ldrb r0,[r3]




mov pc,#0

@只读
@const char *name1 = "hello";
name1:  .byte 'h','e','l','l','o',0

.data  @ 数据段开始 

@ int a = 10;  //全局变量
a:   .word  10
@ int m;
m:   .space 4  
@ char c = 'b';
c:   .byte 'b'

@char  name[] = "hello";
name:  .byte 'h','e','l','l','o',0

@int arr[5];
arr: .space 5*4

@int arr1[5] = {1,2,3,4};
arr1: .word 1,2,3,4,0

.end

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Y_寒酥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值