ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

第10部分- Linux ARM汇编 寻址方式

2021-04-15 19:53:18  阅读:124  来源: 互联网

标签:myvar1 10 myvar2 r1 r2 ldr Linux ARM addr


都遵循gas汇编器的语法。

  • 立即寻址指令后面的地址码部分为立即数

            MOV RO, #1234

  • 寄存器寻址中,操作数在寄存器中,指令执行时直接从寄存器中取值进行操作。

      MOV R0, R1

  • 寄存器移位寻址是ARM指令集特有的寻址方式,和寄存器寻址类似,只是操作前需要对寄存器操作数进行移位操作。

LSL:逻辑左移,移位后寄存器空出的低位补0。

LSR:逻辑右移,移位后寄存器空出的高位补0。

ASR:算术右移,移位过程中,符号位保持不变,如果源操作数是正数,则空出的高位补0,否则补1.

ROR:循环右移,移位后移除的低位填入空出的高位。

RRX:带扩展的循环右移,操作数右移一位,移位空出的高位用C标志的值填充。

      MOV R0, R1, LSL #2

R1寄存器左移两位赋值给R0,指令执行后,R0=R1*4。

  • 寄存器间接寻址:地址码给出的寄存器是操作数的地址指针,所需的操作数保存在寄存器指定的存储单元中。

 

LDR R0, [R1]

将R1寄存器的数值作为地址,取出此地址中的值赋给R0寄存器。

  • 基址寻址是将地址码给出的基址寄存器和偏移量相加,形成操作数的有效地址,所需的操作数保存在有效地址所指向的存储单元中。基址寻址多用于查表和数组访问等操作

LDR R0, [R1, #-4]

寄存器R1的数组减去4作为地址,取出此地址中的值赋值给R0。

  • 多寄存器寻址 : 一条指令最多可以完成16个通用寄存器的传送。

LDMIA R0, {R1, R2, R3, R4}

LDM是数据加载指令,指令的后缀IA表示每次执行完加载操作后R0寄存器的值自增1个字。指令执行后,R1=[R0],R2=[R0+#4],R3=[R0+#8],R4=[R0+#12]。

  • 堆栈寻址是ARM处理器特有的一种寻址方式,堆栈寻址使用特定的指令来完成。

LDMFA/STMFA

LDMEA/STMEA

LDMFD/STMFD

LDMED/STMED

STMFD SP1, {R1-R7, LR}

将R1-R7,LR入栈,多用于保存子程序现场。

LDMFD SP1, {R1-R7, LR}

将数据出栈,放入R0-R7,LR寄存器,多用于恢复程序现场。

  • 块拷贝寻址可实现连续地址数据从存储器的某一位置拷贝到另一位置。

LDMIA/STMIA

LDMDA/STMDA

LDMIB/STMIB

LDMDB/STMDB

LDMIA R0!, {R1-R3}

从R0寄存器的存储单元中读取3个字到R1-R3寄存器中。

STMIA R0!, {R1-R3}

存储在R1-R3寄存器的内容到R0指向ed存储单元。

LDMIA/LDMDA中I表示Increasing,D表示decreasing,A表示After,B表示Before。

  • 相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到的操作数作为有效地址。

BL NEXT

   ...

NEXT:

   ...

BL NEXT是跳到NEXT标号处执行,这里的BL就是采用相对寻址,标号NEXT是偏移量。

Load/store示例

Load示例

定义load.s文件如下:

.data;//数据段

.balign 4  /* 四个字节对齐 */
myvar1: /* 定义变量myvar1 */
    .word 3     /* 值为'3' */
.balign 4 /* 四个字节对齐 */
myvar2: /* 定义变量myvar2 */
    .word 4    /* 值为'4' */
 
.text /* -- 代码段*/
.balign 4 /* 四个字节对齐 */
.global main
main:
    ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */
    ldr r1, [r1]           /* r1 ← *r1 */
    ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */
    ldr r2, [r2]           /* r2 ← *r2 */
    add r0, r1, r2         /* r0 ← r1 + r2 */
    bx lr
 
/* 数据地址 */
addr_of_myvar1 : .word myvar1;//在链接的时候最后确认myvar1的地址
addr_of_myvar2 : .word myvar2;//在链接的时候最后确认myvar2的地址
复制代码

编译:

as -g -o load.o load.s

gcc -o load load.o

 

Store示例

源码如下:

.data;//数据段

.balign 4  /* 四个字节对齐 */
myvar1: /* 定义变量myvar1 */
    .word 0     /* 值为'0' */
.balign 4 /* 四个字节对齐 */
myvar2: /* 定义变量myvar2 */
    .word 0    /* 值为'0' */
 
.text /* -- 代码段*/
.balign 4 /* 四个字节对齐 */
.global main
main:
    
ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */
mov r3,#3
str r3,[r1]//将r3中值保持到[r1],就是myvar1值=3

ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */
mov r3,#4
ldr r3, [r2]           /* r3 ← *r2 */

ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */
ldr r1,[r1];// r1=myvar1值
ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */
ldr r2, [r2]           /* r2 ← *r2 ,就是r2=0*/

add r0, r1, r2         /* r0 ← r1 + r2 ,就是3+0=3*/
bx lr
 
/* 数据地址 */
addr_of_myvar1 : .word myvar1;//在链接的时候最后确认myvar1的地址
addr_of_myvar2 : .word myvar2;//在链接的时候最后确认myvar2的地址
复制代码

as -g -o store.o store.s

gcc -o store store.o

实现了将,

执行验证;

#./store

#echo $?

结果一致。

 

64位Load示例

.arch armv8-a

.data;//数据段

.balign 4  /* 四个字节对齐 */
myvar1: /* 定义变量myvar1 */
    .word 3     /* 值为'3' */
.balign 4 /* 四个字节对齐 */
myvar2: /* 定义变量myvar2 */
    .word 4    /* 值为'4' */
 
.text /* -- 代码段*/
.balign 4 /* 四个字节对齐 */
.global main
main:
    ldr r1, addr_of_myvar1 /* r1 ← &myvar1 */
    ldr r1, [r1]           /* r1 ← *r1 */
    ldr r2, addr_of_myvar2 /* r2 ← &myvar2 */
    ldr r2, [r2]           /* r2 ← *r2 */
    add r0, r1, r2         /* r0 ← r1 + r2 */
    mov x8, 93
	svc 0
 
/* 数据地址 */
addr_of_myvar1 : .word myvar1;//在链接的时候最后确认myvar1的地址
addr_of_myvar2 : .word myvar2;//在链接的时候最后确认myvar2的地址
复制代码

 

编译:

as -g -o load64.o load64.s

gcc -o load64 load64.o

 

64位store示例

.data;//数据段

.balign 4  /* 四个字节对齐 */
myvar1: /* 定义变量myvar1 */
    .word 0     /* 值为'0' */
.balign 4 /* 四个字节对齐 */
myvar2: /* 定义变量myvar2 */
    .word 0    /* 值为'0' */
 
.text /* -- 代码段*/
.balign 4 /* 四个字节对齐 */
.global main
main:
    
ldr x1, addr_of_myvar1 /* r1 ← &myvar1 */
mov x3,#3
str x3,[x1]//将r3中值保持到[r1],就是myvar1值=3

ldr x2, addr_of_myvar2 /* r2 ← &myvar2 */
mov x3,#4
ldr x3, [x2]           /* r3 ← *r2 */

ldr x1, addr_of_myvar1 /* r1 ← &myvar1 */
ldr x1,[x1];// r1=myvar1值
ldr x2, addr_of_myvar2 /* r2 ← &myvar2 */
ldr x2, [x2]           /* r2 ← *r2 ,就是r2=0*/

add x0, x1, x2         /* r0 ← r1 + r2 ,就是3+0=3*/
mov x8, 93
	svc 0 
/* 数据地址 */
addr_of_myvar1 : .dword myvar1;//在链接的时候最后确认myvar1的地址
addr_of_myvar2 : .dword myvar2;//在链接的时候最后确认myvar2的地址
复制代码

as -g -o store64.o store64.s

gcc -o store64 store64.o


标签:myvar1,10,myvar2,r1,r2,ldr,Linux,ARM,addr
来源: https://blog.51cto.com/u_15169172/2709222

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有