简体   繁体   English

我可以使用ARM的LDR指令访问什么地址

[英]What address I could access with LDR instruction of ARM

I'm totally new for ARM assembly code. 我是ARM汇编代码的新手。

I just checked the instruction set and found there is an instruction LDR which could be used as "LDR{}{} Rd, ". 我刚检查了指令集,发现有一条指令LDR可以用作“LDR {} {} Rd,”。

I have two questions about this instruction: 1) Is the address here physical address or virtual address? 关于这条指令,我有两个问题:1)这里的地址是物理地址还是虚拟地址? 2) How could I know which address is "legal" or "readable" for me to load? 2)我怎么知道加载哪个地址“合法”或“可读”? I have no idea about which address I could access. 我不知道我可以访问哪个地址。

I just want to test this instruction so any valid address would be helpful for me. 我只是想测试这条指令,所以任何有效的地址对我都有帮助。

Thank you very much. 非常感谢你。

It depends on what exactly ARM architecture your program runs on. 这取决于程序运行的ARM架构究竟是什么。 If it's a small micro-controller like Cortex-M0 (which is an ARMv6-M) you use physical addresses. 如果它是像Cortex-M0这样的小型微控制器(ARMv6-M),则使用物理地址。 In the Reference Manual of the specific processor you can check what addresses are valid (for instance what is an address range of RAM). 在特定处理器的参考手册中,您可以检查哪些地址有效(例如,RAM的地址范围是什么)。 You also need to remember that usually the address must be aligned to word size (again, it depends on specific version of architecture). 您还需要记住,通常地址必须与字大小对齐(同样,它取决于架构的特定版本)。

If you use "big" ARM processor, like one of Cortex-A (ARMv7-A) or a 64 bit ARM (ARMv8-A) you also use (most probably) some kind of High Level Operating System (for instance Linux) and the processor itself has an MMU. 如果您使用“大”ARM处理器,如Cortex-A(ARMv7-A)或64位ARM(ARMv8-A)之一,您还使用(最可能)某种高级操作系统(例如Linux)和处理器本身有一个MMU。 In that case you passes virtual addresses. 在这种情况下,您传递虚拟地址。 If you use a 32 bit Linux with a standard 3:1 split all addresses below 0xC0000000 (that are aligned) are accessible for userspace program. 如果使用带有标准3:1拆分的32位Linux,则所有低于0xC0000000的地址(已对齐)都可供用户空间程序访问。 BTW you can access unaligned addresses using other instructions (like LDRB, LDRH). 顺便说一句,您可以使用其他指令(如LDRB,LDRH)访问未对齐的地址。

If you're working on Linux, my article might be helpful. 如果您正在使用Linux, 我的文章可能会有所帮助。 This article is quite messy currently, but at least inside there is a quite good set of external links to other articles. 这篇文章目前相当混乱,但至少在内部有一组很好的外部链接到其他文章。

ARMv7-A -R Architecture Reference Manual clearly states that ARMv7-A -R Architecture Reference Manual明确指出

An address used in an instruction, as a data or instruction address, is a Virtual Address (VA). 指令中使用的地址,作为数据或指令地址,是虚拟地址(VA)。

An address held in the PC, LR, or SP, is a VA. PC,LR或SP中保存的地址是VA。

The VA map runs from zero to the size of the VA space. VA映射从零到VA空间的大小。 For ARMv7, the maximum VA space is 4GB, giving a maximum VA range of 0x00000000 - 0xFFFFFFFF. 对于ARMv7,最大VA空间为4GB,最大VA范围为0x00000000 - 0xFFFFFFFF。

Also it is clear that this VA is translated to Physical Address which in turn is used to perform desired operation with physical memory. 同样很清楚,该VA被转换为物理地址,而物理地址又用于利用物理存储器执行期望的操作。 Further on effects of disabling Memory Management Unit (which does actual memory mapping) are described, but this does not negate the fact that address is Virtual Address. 进一步说明了禁用内存管理单元(实际内存映射)的影响,但这并没有否定地址是虚拟地址的事实。

All-in-all with recent ARM architecture you do operate with Virtual Addresses unless you're writing the kernel, which has to deal with setting up paging and address translation. 使用最新的ARM体系结构,除非您正在编写内核(必须处理设置分页和地址转换),否则您将使用虚拟地址进行操作。 And if you're running your code under some Operating System you're all-safe. 如果您在某些操作系统下运行代码,那么您就是安全的。

This leads to answer for your second question. 这导致您回答第二个问题。 As you're secured by OS, you're free to try and access any address you wish, but access to a random address at worst will result in OS terminating your particular application. 当您受到操作系统的保护时,您可以自由尝试访问您希望的任何地址,但在最坏情况下访问随机地址将导致操作系统终止您的特定应用程序。 To identify which addresses you may have access to you may try and run your program under gdb and list all the mapped memory with info proc mappings gdb command. 要确定您可以访问哪些地址,可以尝试在gdb下运行程序,并使用info proc mappings gdb命令列出所有映射的内存。

  1. Unless you're writing kernel / bootloader code, all addresses are always virtual. 除非您正在编写内核/引导加载程序代码,否则所有地址始终是虚拟的。 You can't use physical addresses even if you wanted to. 即使您愿意,也不能使用物理地址。 (Assuming you're writing user-space code that will run under a full-scale OS like Linux. More generally, either you always have virtual addresses or you always have physical addresses. You can't write code that uses some physical and some virtual memory accesses. If you want to do something to a certain physical address, you have to map it into your virtual address space.) (假设您正在编写将在Linux等全面操作系统下运行的用户空间代码。更一般地说,要么总是拥有虚拟地址,要么总是拥有物理地址。您不能编写使用某些物理地址的代码。虚拟内存访问。如果要对某个物理地址执行某些操作,则必须将其映射到虚拟地址空间。)

  2. the stack pointer typically points to valid memory when the OS starts your process. 当OS启动进程时,堆栈指针通常指向有效内存。 Anything you put in the data or bss segments should also be readable. 您放入数据或bss段的任何内容也应该是可读的。

Anything more than this is beyond the scope of a single answer. 除此之外的任何事情都超出了单一答案的范围。 Google up an intro tutorial. 谷歌上了一个介绍教程。

However, since you mention ldr specifically, and it's not just a simple instruction (either a load or a pseudo-instruction to put a compile-time-constant into a register): See Why use LDR over MOV (or vice versa) in ARM assembly? 但是,由于你特别提到了ldr ,它不仅仅是一个简单的指令(将编译时常量放入寄存器的加载或伪指令):请参阅为什么在ARM中使用LDR而不是MOV(反之亦然)部件?

I don't really know ARM asm, I didn't realize the answer was going to be arch-specific. 我真的不知道ARM asm,我没有意识到答案是特定于arch的。 1. and 2. apply to user-space code on all CPUs (on normal OSes with protected memory). 1.和2.适用于所有CPU上的用户空间代码(在具有受保护内存的普通操作系统上)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM