I'm pretty new to assembly. For my third lab in the class it's being taught in, we have to use "LDR" a lot to store parts of different registers into one final register.
It's supposed to take the first byte of the first register, second byte of the second register, third byte of the third register, and fourth byte of the fourth register and store these values into one final register.
The following code, to me, seems like it should do this:
LDR r1, =0x2A078CE2
LDR r2, =0x0C82B182
LDR r3, =0x9F46452E
LDR r4, =0x31F1D1B9
LDRB r6, [r1]
LDRB r7, [r2, #1]
LDRB r8, [r3, #2]
LDRB r9, [r4, #3]
stop B stop
end
The code compiles with 1 warning: ""p1.s", line 309: Warning: A1581W: Added 2 bytes of padding at address 0x16"
Not sure what that means or if its an issue.
Either way, when I debug the code, registers 1 - 4 receive the correct values. But once the LDRB instructions are executed, none of the registers change value. Even after changing the first instruction to LDR r6, [r1], r6 stays at 0.
Completely at a loss here, since I'm using the exact syntax given by my professor
CodePudding user response:
LDR r1, =0x2A078CE2
LDRB r6, [r1]
This says put the value 0x2a078ce2 into register r1 then read from MEMORY at ADDRESS 0x2a078ce2 and get the byte there, zero pad it and put that in r6. If you wanted the lower 8 bits of r1 then you need to use AND. if you wanted say bits 8:15 then you would need to shift right and then use AND, or AND and then shift, your choice.
ldr does a load (from memory at some address). If you want bits from a register then you either need to write the register to memory then read back the byte in question (using some address you safely choose) or just mask and shift (and not use memory at all).
you are wanting r6 = (r1>>0)&0xFF; not r6 = (unsigned char *)r1; (r7 = (r2>>8)&0xFF, etc)
CodePudding user response:
and r1, r1, #0xff
and r2, r2, #0xff<<8
and r3, r3, #0xff<<16
and r4, r4, #0xff<<24
orr r1, r2, r1
orr r3, r4, r3
orr r0, r3, r1
r0 contains the final result.