I'm trying to code a way to add specific halfwords from word-sized numbers in the ARM assembly language. For example, lets say I want to add the first 4 digits of r0=0x3B029BA1 and r1=0x0B54A361 or the middle 4 digits of r0=0x3B029BA1 and r1=0x0B54A361. I can't seem to make this work. This is a shortened example of what I have so far.

LDR r0, =0x3B029BA1;
LDR r1, =0x0B54A361;
LDRH r10, [r1]; 

I'm pretty sure there will need to be an offset for the address in the 3rd line of the code, but I haven't gotten past a halfword just getting into the register 10. Every time I run this code, the correct register values end up in r0 and r1, but nothing at all is appearing in r10. So before I do anything else, I just want to understand why this is happening.

  • 1
    \$\begingroup\$ Is there a reason you would not shift and mask the values? Eg. in C uint32_t r0 = 0x3B029BA1; uint32_t r1 = 0x0B54A361; uint32_t result = ((r0>>8) & 0xFFFF) + ((r1>>8) & 0xFFFF). Also are they signed or unsigned numbers? \$\endgroup\$ – gbulmer Sep 20 '16 at 0:55
  • \$\begingroup\$ Well I'm new to this, and as I side, the offset can come later, right now I just don't understand why nothing at all is appearing in r10. Plus I can only use what we've learned so far. \$\endgroup\$ – RoryHector Sep 20 '16 at 0:58
  • \$\begingroup\$ I rarely write ARM assembler, and am not using my usual computer, so I don't have the ARM manuals to be certain. However, IIRC a LDRx instruction always means load from memory, so LDRH ...,[r1] should mean load from memory using the value in r1 as that memory address. Either you should load the correct two bytes of the value, and not all 4 bytes, or use shift and mask, or look at the MOV instruction for register to register transfers. Please double check as I don't have the ARM manuals, and may be misremembering. I apologise I can't be more help. \$\endgroup\$ – gbulmer Sep 20 '16 at 1:29

LDR and LDRH are instructions for loading a register from memory. You are using R1 as a pointer to memory location 0x0B54A361. R10 then gets loaded with the contents of this memory location (which could be anything, but probably 0 if that particular memory location is not being used).

To move (copy) data from one register to another you should use the MOV instruction. You can combine the move with other operations by using instructions such as AND or ADD, because the destination register can be different from the source registers. You may also be able to apply a shift or rotate with the same instruction.

  • \$\begingroup\$ So it's okay if I leave the initial two lines the same as long as I change the opcode on the third line? While they may technically be memory locations, as long as I can add them and save the value to another register, I'm set. \$\endgroup\$ – RoryHector Sep 20 '16 at 1:35
  • \$\begingroup\$ Yes. The data in R0 and R1 could represent memory locations, but at this point it's just data. \$\endgroup\$ – Bruce Abbott Sep 20 '16 at 1:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.