I couldn't find any tutorial on how to set the flags for the Carry on ARM to 1 or to 0. Can anybody help me out with that?
1 回答
As in put ARM CPU in different modes and linux's irqflags.h, setting the mode, IRQ and carry flags can all be done in the same way.
Generally the macros is like,
.macro set_cflag, temp_reg
mrs \temp_reg, cpsr
bic \temp_reg, \temp_reg, #(1<<29)
msr cpsr_f, \temp_reg
.endm
.macro clear_cflag, temp_reg
mrs \temp_reg, cpsr
orr \temp_reg, \temp_reg, #(1<<29)
msr cpsr_f, \temp_reg
.endm
It is three steps,
- Read the old value.
- Update the flag in a working register.
- Write the value back.
Some additional details are 'atomic' behaviour. Ie, you might need to disable interrupts and memory faults, etc. For some user code or a simple 'polling mode' bare metal, the above is fine.
If you really want to be 'efficient'; looking at your surrounding context and known registers you can execute some instruction that you know will set/clear the carry flag. For instance, if R0 is '0' then adds r0,r0,r0
will clear the carry flag. An instruction like eors R0,R0,R0
will not touch the carry bit. It may depend on whether you also need to know about other NZV bits. The notation 'cpsr_f' will only alter the NZCV bits. You can use msr cpsr_f, #NZCV_bits
if you want to set/clear all of these. Ie, you don't care about the old value of all of them arch restrictions . The other flags, like mode, IRQ, etc will remain untouched.
See also: