当前位置: 首页 > news >正文

泰州制作公司网站重庆seo服务

泰州制作公司网站,重庆seo服务,seo站长网,国家高职示范校建设网站LOAD/STORE MULTIPLE 有时一次加载(或存储)多个值更有效。为此,我们使用LDM(加载多个)和STM(存储多个)。这些指令有一些变化,基本上只在访问初始地址的方式上有所不同。这是…

LOAD/STORE MULTIPLE         

      有时一次加载(或存储)多个值更有效。为此,我们使用LDM(加载多个)和STM(存储多个)。这些指令有一些变化,基本上只在访问初始地址的方式上有所不同。这是我们将在本节中使用的代码。我们将一步一步地研究每一条指令。

.dataarray_buff:.word 0x00000000             /* array_buff[0] */.word 0x00000000             /* array_buff[1] */.word 0x00000000             /* array_buff[2]. This element has a relative address of array_buff+8 */.word 0x00000000             /* array_buff[3] */.word 0x00000000             /* array_buff[4] */.text
.global _start_start:adr r0, words+12             /* address of words[3] -> r0 */ldr r1, array_buff_bridge    /* address of array_buff[0] -> r1 */ldr r2, array_buff_bridge+4  /* address of array_buff[2] -> 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] = 0x04; r6 -> array_buff[2] = 0x05 */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-r5}            /* r5 -> array_buff[1] = 0x01; r4 -> array_buff[0] = 0x00; */bx lrwords:.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             /* address of array_buff, or in other words - array_buff[0] */.word array_buff+8           /* address of array_buff[2] */

        在开始之前,请记住.字指的是32位=4字节的数据(内存)块。这对于理解抵消非常重要。因此,该程序由.data部分组成,我们在其中分配一个包含5个元素的空数组(array_buff)。我们将使用它作为存储数据的可写内存位置。.text部分包含我们的代码以及内存操作指令和一个只读数据池,其中包含两个标签:一个用于具有7个元素的数组,另一个用于“桥接”.text和.data部分,以便我们可以访问.data部分中的array_buff。

adr r0, words+12             /* address of words[3] -> r0 */

      我们使用ADR指令(惰性方法)将第4个(单词[3])元素的地址获取到R0中。我们指向单词数组的中间,因为我们将从那里向前和向后操作。

gef> break _start 
gef> run
gef> nexti

      R0现在包含字[3]的地址,在本例中为0x80B8。这意味着,我们的数组从字[0]的地址开始:0x80AC(0x80B8–0xC)。

gef> x/7w 0x00080AC
0x80ac <words>: 0x00000000 0x00000001 0x00000002 0x00000003
0x80bc <words+16>: 0x00000004 0x00000005 0x00000006

      我们用array_buff数组的第一个(array_buff[0])和第三个(array_buff[2])元素的地址来准备R1和R2。一旦获得地址,我们就可以开始对其进行操作。

ldr r1, array_buff_bridge    /* address of array_buff[0] -> r1 */
ldr r2, array_buff_bridge+4  /* address of array_buff[2] -> r2 */

    在执行上述两条指令后,R1和R2包含array_buff[0]和array_bufp[2]的地址。

gef> info register r1 r2
r1      0x100d0     65744
r2      0x100d8     65752

      下一条指令使用LDM从R0指向的内存中加载两个字值。因此,因为我们早些时候让R0指向单词[3]元素,单词[3]值变为R4,单词[4]值变为R5。

ldm r0, {r4,r5}              /* words[3] -> r4 = 0x03; words[4] -> r5 = 0x04 */

    我们用一个命令加载了多个(2个数据块),该命令设置R4=0x00000003和R5=0x00000004。

gef> info registers r4 r5
r4      0x3      3
r5      0x4      4

   到目前为止还不错。现在让我们执行STM指令,将多个值存储到内存中。我们代码中的STM指令从寄存器R4和R5获取值(0x3和0x4),并将这些值存储到R1指定的内存位置。我们之前将R1设置为指向第一个array_buff元素,因此在该操作之后,array_buff[0]=0x00000003,array_baff[1]=0x00000004。如果未另行指定,LDM和STM在字的一个步长上运算(32位=4字节)。

stm r1, {r4,r5}              /* r4 -> array_buff[0] = 0x03; r5 -> array_buff[1] = 0x04 */

     值0x3和0x4现在应该存储在存储器地址0x100D0和0x100D4处。以下指令检查地址0x000100D0处的两个存储器字。

gef> x/2w 0x000100D0
0x100d0 <array_buff>:  0x3   0x4

       如前所述,LDM和STM有变化。变体的类型由指令的后缀定义。示例中使用的后缀为:-IA(在之后增加)、-IB(在之前增加)、-DA(在后面减少)、-DB(在前面减少)。这些变体访问第一个操作数指定的内存(存储源或目标地址的寄存器)的方式不同。在实践中,LDM与LDMIA相同,这意味着要加载的下一个元素的地址在每次加载后都会增加。通过这种方式,我们从第一个操作数指定的内存地址(存储源地址的寄存器)获得顺序(正向)数据加载。

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 */

   在执行上述两条指令之后,寄存器R4-R6和存储器地址0x000100D0、0x000100D4和0x000100D8包含值0x3、0x4和0x5。

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

          当我们使用LDMDA指令时,一切都开始向后操作。R0指向单词[3]。当加载开始时,我们向后移动,并将单词[3]、单词[2]和单词[1]加载到R6、R5、R4中。是的,寄存器也是向后加载的。因此,在指令完成后,R6=0x00000003,R5=0x00000002,R4=0x00000001。这里的逻辑是我们向后移动,因为我们在每次加载后递减源地址。发生反向注册表加载是因为每次加载时,我们都会减少内存地址,从而减少注册表编号,以跟上内存地址越高,注册表编号越高的逻辑。查看LDMIA(或LDM)示例,我们首先加载较低的注册表,因为源地址较低,然后加载较高的注册表,原因是源地址增加。

加载倍数,在以下时间后递减:

ldmda r0, {r4-r6} /* words[3] -> r6 = 0x03; words[2] -> r5 = 0x02; words[1] -> r4 = 0x01 */

执行后的寄存器R4、R5和R6:

gef> info register r4 r5 r6
r4     0x1    1
r5     0x2    2
r6     0x3    3

存储倍数,之后递减。

stmda r2, {r4-r6} /* r6 -> array_buff[2] = 0x02; r5 -> array_buff[1] = 0x01; r4 -> array_buff[0] = 0x00 */

array_buff[2]、array_buff[1]、array_bbuff[0]执行后的内存地址:

gef> x/3w 0x100D0
0x100d0 <array_buff>: 0x00000000 0x00000001 0x00000002

存储倍数,递减之前:

stmdb r2, {r4-r5} /* r5 -> array_buff[1] = 0x01; r4 -> array_buff[0] = 0x00; */

array_buff[1]和array_bufp[0]执行后的内存地址:

gef> x/2w 0x100D0
0x100d0 <array_buff>: 0x00000000 0x00000001

PUSH AND POP

     进程中有一个名为Stack的内存位置。堆栈指针(SP)是一个寄存器,在正常情况下,它总是指向堆栈内存区域中的地址。应用程序经常使用Stack进行临时数据存储。如前所述,ARM使用加载/存储模型进行内存访问,这意味着指令LDR/STR或其衍生物(LDM../STM..)用于内存操作。在x86中,我们使用PUSH和POP从堆栈加载和存储。在ARM中,我们也可以使用以下两条指令:

当我们把一些东西推到Full Descending(第7部分:堆栈和函数中关于堆栈差异的更多信息)堆栈上时,会发生以下情况:

  • 首先,SP中的地址减少4。
  • 其次,信息被存储到SP指向的新地址

当我们从堆栈中弹出某个东西时,会发生以下情况:

  •   当前SP地址处的值被加载到某个寄存器中,
  •   SP中的地址增加4。

在以下示例中,我们同时使用PUSH/POP和LDMIA/STMDB:

.text
.global _start_start:mov r0, #3mov r1, #4push {r0, r1}pop {r2, r3}stmdb sp!, {r0, r1}ldmia sp!, {r4, r5}bkpt

让我们来看看这个代码的反汇编。

azeria@labs:~$ as pushpop.s -o pushpop.o
azeria@labs:~$ ld pushpop.o -o pushpop
azeria@labs:~$ objdump -D pushpop
pushpop: file format elf32-littlearmDisassembly of section .text:00008054 <_start>:8054: e3a00003 mov r0, #38058: e3a01004 mov r1, #4805c: e92d0003 push {r0, r1}8060: e8bd000c pop {r2, r3}8064: e92d0003 push {r0, r1}8068: e8bd0030 pop {r4, r5}806c: e1200070 bkpt 0x0000

    正如您所看到的,我们的LDMIA和STMDB指令被转换为PUSH和POP。这是因为PUSH是STMDB-sp!的同义词!,reglist和POP是LDMIA sp的同义词!reglist(请参阅ARM手册)

让我们在GDB中运行此代码。

gef> break _start
gef> run
gef> nexti 2
[...]
gef> x/w $sp
0xbefff7e0: 0x00000001

  运行前两条指令后,我们快速检查了SP指向的内存地址和值。下一条PUSH指令应将SP减少8,并将R1和R0的值(按顺序)存储到堆栈中。

gef> nexti
[...] ----- Stack -----
0xbefff7d8|+0x00: 0x3 <- $sp
0xbefff7dc|+0x04: 0x4
0xbefff7e0|+0x08: 0x1
[...] 
gef> x/w $sp
0xbefff7d8: 0x00000003

   接下来,这两个值(0x3和0x4)从堆栈弹出到寄存器中,使得R2=0x3和R3=0x4。SP增加8:

gef> nexti
gef> info register r2 r3
r2     0x3    3
r3     0x4    4
gef> x/w $sp
0xbefff7e0: 0x00000001

http://www.hkea.cn/news/32251/

相关文章:

  • 适合友情链接的网站排名函数
  • 开发公司岗位设置广州seo招聘网
  • 国内web设计网站宣传推广
  • 深圳高端网站定制公司小时seo
  • wordpress主菜单下拉箭头怎么设置台州seo排名优化
  • 网站系统管理员模块关键词查找工具
  • 望江县建设局网站外贸seo推广招聘
  • 微信网站上传图片手机怎么制作网站
  • 简单做网站需要学什么搜索引擎有哪些网站
  • 网站备案信息加到哪里如何进行网站推广
  • 昭通网站制作aso优化技巧
  • 制作网站时怎样做滚动字幕新网站多久会被百度收录
  • 余姚物流做网站微信指数是搜索量吗
  • 怎样做网站轮播今日国内重大新闻事件
  • 想给大学做网站百度网盘搜索神器
  • jsp网站开发论文官方app下载安装
  • 关于机场建设的网站今日疫情最新情况
  • 网站域名注册服务商google浏览器官方
  • 通过网站开发工具怎么改自动跳网站百度指数有哪些功能
  • 可以发锚文本的网站百度搜索官方网站
  • 东莞网站建设企慕简述如何优化网站的方法
  • 可以做网站的公司seo外包
  • 自己怎么做网站视频赚钱5g网络优化培训
  • 数据库修改网站管理员密码seo网站有优化培训吗
  • 福田做商城网站建设找哪家公司好抖音怎么运营和引流
  • 厘米售卡站怎么做网站禁止搜索引擎收录的方法
  • 网站首页滚动图片怎么做谷歌搜索关键词排名
  • 嵩县网站开发友情链接获取的途径有哪些
  • 国家企业信息公示网(广东)海南快速seo排名优化
  • 高端网站设计 上海徐州seo排名公司