Trying to understand an assembly line of ARM7

3.3k views Asked by At

I have this assembly line :

01000AD8: 979FF103      LDRLS    PC,[PC,R3,LSL #2]

With PC = 0x01000AD8

R3 = 0x00000008

CDPS = 800000D3 (so C=0, Z=0)

When I execute this line, the new value for PC should be(if I understand LDRLS correctly*)

PC = 0x01000AD8 + 0x00000008 * 4 = 0x01000AF8

But instead the result is 0x00000BAC

Why?

Maybe I could add that the MMU is activated when this line code is executed.

P.S. * I didn't found the meaning of "LS" in LDRLS in my research...

EDIT : added CPSR value

2

There are 2 answers

4
Raymond Chen On

First problem: Page A2-11:

When executing an ARM instruction, PC reads as the address of the current instruction plus 8.

You forgot to add 8 to PC.

Second problem: Page A8-124:

Load Register calculates an address from a base register value and an offset register value, loads a word from memory, and writes it to a register.

You forgot the "loads a word from memory" step.

(The page numbers are from the ARM Architecture Reference Manual for ARMv7-A. Your page numbers may differ.)

0
old_timer On

The PC is always two instructions ahead when used as an operand so add 8 if arm mode and 4 if thumb mode.

LDR is the instruction: load register. The LS means if lower or same LDREQ would be load if equal. Search for "condition codes" in the arm arm. The top four bits in the instruction 0x9 in this case is the LS, execute if lower or same. Most instructions have those bits as 0xE meaning always execute.

All of the ARM instructions use the upper four bits as a condition code, basically on an instruction by instruction basis you can conditionally execute, in this case it will only perform the LDR if the C flag is clear or the Z flag is set. IF it performs the load then it is the address as you were calculating it, plus 8 because the PC input to the address calculation is two instructions ahead of the starting address, then the result is a load from that address into the PC so basically this is a conditional branch to a computed address. A branch table. Normally you would have a branch table with [ra,rb,lsl #2] where ra is the base address of the branch table, rb is the ones based index into that table (element number 0 or 1 or 2) and lsl 2 turns the index into a word address since these are 32 bit instructions. the table contains addresses to branch destinations. The PC being used as the base means the next instruction after this instruction is probably an unconditional branch to non-conditional case if not LS then branch over the table, the instruction after that is the R3 = 0 case the one after that R3 = 1 case and so on. if the compiler knew that R3 could never be smaller than some number then it may have used more instructions after this one before moving over/around the table.

Anyway look at an ARM ARM (now called something like the ARMv5 ARM ARM or legacy ARM ARM or something like that). search for "the condition field" or "condition codes" to find the table. The mnemonic extension is tacked onto the instruction ADD if z flag is set is an ADDEQ. Subtract if the N flag is set is SUBMI, etc.