1
votes

I'm totally new for ARM assembly code.

I just checked the instruction set and found there is an instruction LDR which could be used as "LDR{}{} Rd, ".

I have two questions about this instruction: 1) Is the address here physical address or virtual address? 2) How could I know which address is "legal" or "readable" for me to load? 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.

3
@Craig That's only the ldr rt, =constant form (it's the = which makes all the difference); I read the question as referring to ldr rt, <label>, which is just syntax for the fundamental (and very real) "load register from memory" instruction with a PC-relative immediate offset. I guess the question could do with clarifying...Notlikethat
@CraigEstey , please check the comment of Notlikethat, my question is related to the instruction LDR not the pseudo one, thanks.S.Wan

3 Answers

2
votes

It depends on what exactly ARM architecture your program runs on. If it's a small micro-controller like Cortex-M0 (which is an ARMv6-M) you use physical addresses. In the Reference Manual of the specific processor you can check what addresses are valid (for instance what is an address range of 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. 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. BTW you can access unaligned addresses using other instructions (like LDRB, LDRH).

If you're working on Linux, my article might be helpful. This article is quite messy currently, but at least inside there is a quite good set of external links to other articles.

1
votes
  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.)

  2. the stack pointer typically points to valid memory when the OS starts your process. Anything you put in the data or bss segments should also be readable.

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?

I don't really know ARM asm, I didn't realize the answer was going to be arch-specific. 1. and 2. apply to user-space code on all CPUs (on normal OSes with protected memory).

1
votes

ARMv7-A -R Architecture Reference Manual clearly states that

An address used in an instruction, as a data or instruction address, is a Virtual Address (VA).

An address held in the PC, LR, or SP, is a VA.

The VA map runs from zero to the size of the VA space. For ARMv7, the maximum VA space is 4GB, giving a maximum VA range of 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. 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. 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.