草庐IT

寄存器内存读写指令(一) —— 单寄存器读写 LDR / STR

仲夏夜之梦~ 2025-06-21 原文

CPU在处理C语言的 a++ 操作时,变量a因为是放在在内存里的,需要先把a从内存中读取到寄存器中,运算完毕后再保存到内存中。

因此,下面要介绍的是单个寄存器的读写

  • 一个寄存器的数据写入到内存              —— STR指令
  • 从内存中读取数据保存到一个寄存器       —— LDR指令

         目录

1、基本内存读写指令(4个字节读写)

(1) 写内存 STR

(2) 读内存 LDR

2、内存的其他读写方式(1个字节读写、2个字节读写)

(1) 加后缀 B(1个字节的读写)

(2) 加后缀 H(2个字节的读写)


1、基本内存读写指令(4个字节读写)

(1) 写内存 STR

STR 的作用是将数据保存到内存中,默认情况下,一次会向内存中写入4个字节

指令格式:STR  第一操作寄存器,  [ 第二个操作寄存器]

  • 第一操作寄存器:保存数据的寄存器
  • 第二个操作寄存器:保存内存地址的寄存器(即要写入到内存中的哪个地址)
MOV R1, #0x000000FF    
MOV R2, #0x40000000
MOV R3, #4

@ 基本使用方式
STR R1, [R2]            @ 将R1寄存器中的数据保存到 R2 的地址
                        @ 也就是 将0x000000FF保存到内存中的 0x40000000地址

@ 基址加变址寻址 —— 前索引(地址先自增,然后再存)  
STR R1, [R2, R3]        @ 将R1寄存器中的数据保存到 R2+R3 的地址  —— R2 保存的地址不自增                
STR R1, [R2, #4]        @ 与上述写法等价          —— R2 保存的地址不自增
STR R1, [R2, #4]!       @ 上述写法实现的功能一样   —— R2 保存的地址自增4

@ 基址加变址寻址 —— 后索引(先存,地址再自增)
STR R1, [R2], #4        @ 先将R1寄存器中的数据保存到 R2 的地址,然后R2中保存的地址自增4

注意:内存中不同的区域有不同的作用,有的区域存放的内容可读可写,有的区域存放的内容可执行,这里的0x40000000地址可读可写

(2) 读内存 LDR

LDR 的作用是从内存中加载(读取)数据,默认情况下,一次从内存中读取4个字节

指令格式:LDR 第一操作寄存器,  [ 第二操作寄存器 ]

  • 第一操作寄存器:用于存储读取到的数据的寄存器
  • 第二操作寄存器:保存内存地址的寄存器(即要从内存中的哪个地址读)
MOV R1, #0x000000FF
MOV R2, #0x40000000
STR R1, [R2]

@ 基本使用方式	
LDR R3, [R2]            @ 从R2寄存器指向的地址读取数据,保存到R3寄存器

@ 基址加变址寻址 —— 前索引(地址先自增,然后读)  
LDR R1, [R2, R3]        @ 读取内存中 R2+R3 地址处的数据保存到R1  —— R2 保存的地址不自增                
LDR R1, [R2, #4]        @ 与上述写法等价          —— R2 保存的地址不自增
LDR R1, [R2, #4]!       @ 上述写法实现的功能一样   —— R2 保存的地址自增4

@ 基址加变址寻址 —— 后索引(先读,地址再自增)
LDR R1, [R2], #4        @ 先将R1寄存器中的数据保存到 R2 的地址,然后R2中保存的地址自增4

2、内存的其他读写方式(1个字节读写、2个字节读写)

STR / LDR 一次读/写4个字节,处理器中的数据类型还有Byte、Halfword,分别对应C语言中char类型、short类型,如果要对这两种类型进行操作,上面的指令不大适用。

因此,ARM在上述指令的基础上加一个后缀,以满足操作1个字节 或 2个字节 的需求。

(1) 加后缀 B(1个字节的读写)

以写为例,如果我们要向内存中写入一个字节,那就可以使用指令 STRB,指令使用格式和上述基本指令一样。

MOV R1, #0xFFFFFFFF
MOV R2, #0x40000000
STRB R1, [R2]         

我们发现R1寄存器中的最低位的1个字节被写入到内存里。 

(2) 加后缀 H(2个字节的读写)

以写为例,如果我们要向内存中写入一个字节,那就可以使用指令 STRH

MOV R1, #0xFFFFFFFF
MOV R2, #0x40000000
STRB R1, [R2]         

 我们发现R1寄存器中的最低位的2个字节被写入到内存里。

 

有关寄存器内存读写指令(一) —— 单寄存器读写 LDR / STR的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  3. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  4. python - Ruby 相当于 Python str[3 :] - 2

    是否有Ruby等效于Python的方法来获取在字符串末尾结束的子字符串,如str[3:]?必须输入字符串的长度并不方便。 最佳答案 传递最后一个元素=-1的范围str[3..-1] 关于python-Ruby相当于Pythonstr[3:],我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/12978768/

  5. ruby - 为什么 Ruby 返回 `str[-1..1]` 它做了什么? - 2

    假设我们有一个字符串str。如果str仅包含一个字符,例如str="1",则str[-1..1]返回1.但是如果str的size(length)比一个长,比如str="anythingelse",然后str[-1..1]返回""(空字符串)。为什么Ruby会这样解释字符串切片? 最佳答案 这种行为正是字符范围的工作方式。范围开始是-1,这是字符串中的最后一个字符。范围结束为1,即从开始算起的第二个位置。所以对于单字符字符串,这相当于0..1,也就是那个单个字符。对于双字符字符串,这是1..1,即第二个字符。对于三个字符的字符串,这是

  6. ruby-on-rails - HTTParty 的内存问题和下载大文件 - 2

    这会导致Ruby出现内存问题吗?我知道如果大小超过10KB,Open-URI会写入TempFile。但是HTTParty会在写入TempFile之前尝试将整个PDF保存到内存吗?src=Tempfile.new("file.pdf")src.binmodesrc.writeHTTParty.get("large_file.pdf").parsed_response 最佳答案 您可以使用Net::HTTP。参见thedocumentation(特别是标题为“流媒体响应机构”的部分)。这是文档中的示例:uri=URI('http://e

  7. ruby - 在 Ruby 中实现 to_int 和 to_str 的后果 - 2

    我haveaclass它公开了一个字符串值和一个int值(分别是命令输出和退出代码)。除了通过to_s和to_i公开它们之外,我还使用to_str和to_int,如下所示:classStatusdefto_s@outputendalias:to_str:to_sdefto_i@status.exitstatusendalias:to_int:to_iend我的想法是能够在尽可能多的情况下使用这个对象。将其强制转换为字符串或整数会增加可用性。例如,我可以将对象与字符串连接起来:a_string="Outputwas:"+results(我想用这个作为int强制转换的例子,但是Fixnum

  8. Ruby - 相当于 Python __str__() 方法? - 2

    在Ruby中,是否存在可以在Python类上定义的与__str__()方法等效的方法? 最佳答案 你可以使用to_s。http://briancarper.net/2006/09/26/ruby-to_s-vs-to_str/ 关于Ruby-相当于Python__str__()方法?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/134969/

  9. ruby-on-rails - 内存中具有相同 ID 的更多对象? - 2

    在部署在heroku上的Rails应用程序(v:3.1)中,我在内存中获得了更多具有相同ID的对象。我的heroku控制台日志:>>Project.find_all_by_id(92).size=>2>>ActiveRecord::Base.connection.execute('select*fromprojectswhereid=92').to_a.size=>1这怎么可能?可能是什么问题? 最佳答案 解决方案根据您的SQL查询,您的数据库中显然没有重复条目。也许您的类项目中的size或length方法已被覆盖。我试过find_

  10. ruby - rails 3.0.7 内存泄漏 - 2

    我的两个不同的Rails应用程序的内存有一些奇怪的问题。这两个应用程序都使用rails3.0.7。每个Controller请求分配20-30-50MB的内存。在生产模式下,这个数量减少到5-10。但这是同样的事情。这是两个应用程序使用的gem列表:gem'pg'gem'haml'gem'sass'gem'devise'gem'simple_form'gem'state_machine'gem"globalize3","0.1.0.beta"gem"easy_globalize3_accessors"gem'paperclip'gem'andand'关闭所有这些gem不会给我任何结果。我

随机推荐