Should be easy for you to solve. In Keil Uvision5 , M3 cortex Please show me how
ID: 3738563 • Letter: S
Question
Should be easy for you to solve. In Keil Uvision5 , M3 cortex
Please show me how to change line 14. I need to change ADC to anyone of these 1. LDR 2. MOV 3. CMP 4. BEQ 5. CLZ 6. ADD 7. LSL 8. BNE
however, as it is, the code should result in R1 = 0x0000000E .If i change ADC to ADD the result for R1 changes. Below is the copy paste code. I need to keep R1 as 0x0000000E. thanks
thumbs up for good answer.
===code===
AREA name, CODE, READONLY
EXPORT __main
__main
LDR r0, = 0x7E0C0A2B
MOV r1, #0 ;r1 = 0
MOV r2,r0 ; r2 = r0
MOV r4, #0 ; r4 = 0
countone ; loop
MOVS r2, r2, LSR #1
ADC r1,r1, r4 ; r1 = r1 + r4
CMP r2, #0
BNE countone
stop B stop
END
Explanation / Answer
Focus on these two instruction:
MOVS r2, r2, LSR #1
ADC r1,r1, r4
ADC : r1 = r1+r4+C where C is carry flag. Now value in C depends upon the operation LSR in the first instruction. What LSR does is, it will remove LSB and pad one 0 in the MSB, the poped out LSB is saved in the C. So basically if you get lsb of r2, then add that LSB using normal ADD instruction. Now you can get LSB in a number of ways, easiest of which is using CLZ instruction.
CLZ Rd, Rm : returns number of leading 0's in the register Rm into Rd. So if Rm is set to 0, all the bits will be zero and Rd will have 32(for a 32 bit register) and if LSB itself is 1 then Rd will have 0 as there are no leading 0's. To sum up, use below instructions to replace ADC:
CLZ r3, r2
ADD r1,r1,r4
; Now Add carry bit
CMP r3, #0
BNE JUMP_TO_SOME_NEXT_INSTRUCTION ; if r3 not equal to 0, then LSB is 0, dont perform ADD as adding 0 doesn't make sense
ADD r1, r1, #1 ; if r3 is set to 0 then LSB is 1,add 1 to r1