当前位置:网站首页>Arm V7 continuous load / store
Arm V7 continuous load / store
2022-06-25 12:12:00 【xiaozhiwise】
/*
* 2018/12/18 10:15 qing
*/
/*
* Continuous loading / Storage
*/
Use LDM(load multiple) as well as STM(store multiple)
stmdb r0!, {r4-r11, r14} /* Register R4~R11 Also save to stack r0 in [[ From register to memory ]] */
ldmia r0!, {r4-r11, r14} /* From the stack r0 Back to R4~R11,R14 [ [ From memory to register ]] */
.data
array_buff:
.word 0x00000000 /* array_buff[0] */
.word 0x00000000 /* array_buff[1] */
.word 0x00000000 /* array_buff[2] This item points to array_buff+8 The pointer to */
.word 0x00000000 /* array_buff[3] */
.word 0x00000000 /* array_buff[4] */
.text
.global main
main:
adr r0, words + 12 /* wrods[3] The address of ---> r0 */
ldr r1, array_buff_bridge /* array_buff[0] The address of -> r1 */
ldr r2, array_buff_bridge + 4 /* array_buff[2] The address of -> r2 */
ldm r0, {r4, r5} /* words[3] --> r4 = 0x03; words[4] --> r5 = 0x04 */
stm r1, {r4, r5} /* r4 --> array_buff[0] = 0x03; r5 --> array_buff[1] = 0x04 */
ldmia r0, {r4-r6} /* words[3] --> r4 = 0x03, words[4] --> r5 = 0x04; words[5] --> r6 = 0x05 */
stmia r1, {r4-r6} /* r4 --> array_buff[0] = 0x03; r5 --> array_buff[1] = 0x4; r6 --> array_buff[2] = 0x5 */
ldmib r0, {r4-r6} /* words[4] --> r4 = 0x04; words[5] --> r5 = 0x05; words[6] --> r6 = 0x06 */
stmib r1, {r4-r6} /* r4 --> array_buff[1] = 0x04; r5 --> array_buff[2] = 0x05; r6 --> array_buff[3] = 0x06 */
ldmda r0, {r4-r6} /* words[3] --> r6 = 0x03; words[2] --> r5 = 0x02; words[1] --> r4 = 0x01 */
ldmdb r0, {r4-r6} /* words[2] --> r6 = 0x02; words[1] --> r5 = 0x01; words[0] --> r4 = 0x00 */
stmda r2, {r4-r6} /* r6 --> array_buff[2] = 0x02; r5 --> array_buff[1] = 0x01; r4 --> array_buff[0] = 0x00 */
stmdb r2, {r4-r6} /* r5 --> array_buff[1] = 0x01; r4 --> array_buff[0] = 0x00 */
bx lr
.words:
.word 0x00000000 /* words[0] */
.word 0x00000001 /* words[1] */
.word 0x00000002 /* words[2] */
.word 0x00000003 /* words[3] */
.word 0x00000004 /* words[4] */
.word 0x00000005 /* words[5] */
.word 0x00000006 /* words[6] */
array_buff_bridge:
.word array_buff /* array_buff[0] address */
.word array_buff + 8 /* array_buff[2] address */
.word The identification is for the memory with a length of 32 Bit data block as a reference . This is important for understanding offsets in your code .
So the program consists of .data Data composed of segments , A length of... Will be requested in the memory 5 Of 4 Byte array array_buff. All our memory storage operations , All are read and write to the data segment in the memory .
and .text The end contains our code for memory operations and two read-only tags ,
A tag is an array of seven elements , The other is to link .text Paragraph and .data The existence of a segment is for array_buff References to .
/*
* Let's start line by line analysis
*/
adr r0, words+12 /* words[3] The address of -> r0 */
use ADR Command to get words[3] The address of , Coexist to R0 in . We chose a middle position because we have to do forward and backward operations later .
gef> break _start
gef> run
gef> nexti
R0 There is now words[3] The address of the , That is to say 0x80B8. in other words , Our array word[0] The address is :0x80AC(0x80B8-0XC).
gef> x/7w 0x00080AC
0x80ac <words>: 0x00000000 0x00000001 0x00000002 0x00000003 /* 0x80ac 80B0 80B4 80B8 */
0x80bc <words+16>: 0x00000004 0x00000005 0x00000006 /* 0x80bc 80C0 80C4 */
Next, we will R1 and R2 Point to array_buff[0] as well as array_buff[2]. After getting these pointers , We can manipulate this array .
ldr r1, array_buff_bridge /* array_buff[0] The address of -> r1 */
ldr r2, array_buff_bridge+4 /* array_buff[2] The address of -> r2 */
After executing the above two instructions ,R1 and R2 The change of .
gef> info register r1 r2
r1 0x100d0 65744 /* 0x100d0 = 65744 */
r2 0x100d8 65752 /* 0x100d8 = 65752 */
The next one LDM Command from R0 Two words of data are loaded in the memory pointed to . because R0 Point to words[3] At the beginning of , therefore words[3] The value is assigned to R4,words[4] The value is assigned to R5.
ldm r0, {r4,r5} /* words[3] -> r4 = 0x03; words[4] -> r5 = 0x04 */
So we load two data blocks with one instruction , And put it in R4 and R5 in .
gef> info registers r4 r5
r4 0x3 3
r5 0x4 4
STM Instructions will be R4 And R5 The value in 0x3 and 0x4 Store in R1 Point to memory . here R1 Pointing to array_buff[0], in other words array_buff[0] = 0x00000003
as well as array_buff[1] = 0x00000004 . If not specified ,LDM And STM The smallest unit of instruction operation is a word ( Four bytes ).
stm r1, {r4,r5} /* r4 -> array_buff[0] = 0x03; r5 -> array_buff[1] = 0x04 */
value 0x3 And 0x4 It's stored in R1 Where to point 0x100D0 as well as 0x100D4.
gef> x/2w 0x000100D0
0x100d0 <array_buff>: 0x00000003 0x00000004
I said before LDM and STM There are many forms . Different forms of extended characters have different meanings :
IA(increase after)
IB(increase before)
DA(decrease after)
DB(decrease before)
The main basis for these extensions is , The pointer to the source address or destination address is increased or decreased before accessing memory , Or increase or decrease after accessing memory . as well as ,LDM And LDMIA Function the same ,
The address is added after the loading operation is completed . In this way , We can serially load data from the memory pointed to by a pointer to the register forward or backward ,
Or store data in memory . The following schematic code .
ldmia r0, {r4-r6} /* words[3] -> r4 = 0x03, words[4] -> r5 = 0x04; words[5] -> r6 = 0x05; */
stmia r1, {r4-r6} /* r4 -> array_buff[0] = 0x03; r5 -> array_buff[1] = 0x04; r6 -> array_buff[2] = 0x05 */
After executing these two codes ,R4 To R6 The memory address and value accessed by the register are 0x000100D0 , 0x000100D4 , as well as 0x000100D8 , The value corresponds to 0x3,0x4, as well as 0x5 .
gef> info registers r4 r5 r6
r4 0x3 3
r5 0x4 4
r6 0x5 5
gef> x/3w 0x000100D0
0x100d0 <array_buff>: 0x00000003 0x00000004 0x00000005
and LDMIB The instruction will first add... To the address pointed to 4 , Then load the data into the register . So the pointer will also be added when loading for the first time 4 ,
So what is stored in the register is 0x4 (words[4]) instead of 0x3 (words[3])
dmib r0, {r4-r6} /* words[4] -> r4 = 0x04; words[5] -> r5 = 0x05; words[6] -> r6 = 0x06 */
stmib r1,{r4-r6} /* r4 -> array_buff[1] = 0x04; r5 -> array_buff[2] = 0x05; r6 -> array_buff[3] = 0x06 */
After execution
gef> x/3w 0x100D4
0x100d4 <array_buff+4>: 0x00000004 0x00000005 0x00000006
gef> info register r4 r5 r6
r4 0x4 4
r5 0x5 5
r6 0x6 6
When used LDMDA When the command , The reverse operation is performed .R0 Point to words[3], When loading data, the loading direction of the data changes to loading words[3],words[2],words[1] Value to R6,R5,R4 in .
The reason for this loading process is that we LDM The suffix of the instruction is DA, That is, after the loading operation is completed , Will decrement the pointer . Note that the register operation in subtraction mode is reversed ,
The reason for this setting is to maintain the principle of allowing large numbered registers to access high address memory .
Load more than once , Post subtraction :
ldmda r0, {r4-r6} /* words[3] -> r6 = 0x03; words[2] -> r5 = 0x02; words[1] -> r4 = 0x01 */
After performing ,R4-R6 Value :
gef> info register r4 r5 r6
r4 0x1 1
r5 0x2 2
r6 0x3 3
Load more than once , Pre subtraction :
ldmdb r0, {r4-r6} /* words[2] -> r6 = 0x02; words[1] -> r5 = 0x01; words[0] -> r4 = 0x00 */
After performing ,R4-R6 Value :
gef> info register r4 r5 r6
r4 0x0 0
r5 0x1 1
r6 0x2 2
Multiple storage , Post subtraction :
stmda r2, {r4-r6} /* r6 -> array_buff[2] = 0x02; r5 -> array_buff[1] = 0x01; r4 -> array_buff[0] = 0x00 */
After performing ,array_buff[2],array_buff[1], as well as array_buff[0] Value :
gef> x/3w 0x100D0
0x100d0 <array_buff>: 0x00000000 0x00000001 0x00000002
Multiple storage , Pre subtraction :
stmdb r2, {r4-r5} /* r5 -> array_buff[1] = 0x01; r4 -> array_buff[0] = 0x00; */
After performing ,array_buff[1], as well as array_buff[0] Value :
gef> x/2w 0x100D0
0x100d0 <array_buff>: 0x00000000 0x00000001
边栏推荐
- Eureka accesses the console and reports an error: whitelabel error page
- JS to realize the calculation of discrete aggregation points
- Develop two modes of BS mode verification code with VFP to make your website more secure
- 揭秘GaussDB(for Redis):全面对比Codis
- . Using factory mode in net core
- confluence7.4.X升级实录
- 20、wpf之MVVM命令绑定
- ARM V7 协处理器
- VFP develops a official account to receive coupons, and users will jump to various target pages after registration, and a set of standard processes will be sent to you
- 属性分解 GAN 复现 实现可控人物图像合成
猜你喜欢

黑马畅购商城---2.分布式文件存储FastDFS

2022年首期Techo Day腾讯技术开放日将于6月28日线上举办

A set of automated paperless office system (oa+ approval process) source code: with data dictionary

一套自动化无纸办公系统(OA+审批流)源码:带数据字典

20、wpf之MVVM命令绑定

The service layer reports an error. The XXX method invalid bound statement (not found) cannot be found

confluence7.4.X升级实录

Dark horse shopping mall ---1 Project introduction - environment construction

How terrible is it not to use error handling in VFP?

Old ou, a fox friend, has had a headache all day. The VFP format is always wrong when it is converted to JSON format. It is actually caused by disordered code
随机推荐
Why should Apple change objc_ Type declaration for msgsend
依概率收敛
Hook技术
Simple use of stream (II)
Why can't the form be closed? The magic of revealing VFP object references
Dark horse shopping mall ---6 Brand, specification statistics, condition filtering, paging sorting, highlighting
19、wpf之事件转命令实现MVVM架构
如果你也想做自媒体,不妨听大周给您点建议
Quarkus SaaS dynamic data source switching implementation, simple and perfect
Effective reading of literature
PD1.4转HDMI2.0转接线拆解。
做自媒体视频需要怎么做才能年收入一百万?
实现领域驱动设计 - 使用ABP框架 - 系列文章汇总
Dark horse shopping mall ---8 Microservice gateway and JWT token
VFP function to summarize all numeric columns of grid to cursor
揭秘GaussDB(for Redis):全面对比Codis
Real software developers will use this method to predict the future
一款好用的印章设计工具 --(可转为ofd文件)
Cesium building loading (with height)
Kotlin学习笔记