Bic Instruction

Hello I just have a basic question on some bit clearing in Assembly. Here is what I am trying below.

MOV R0, #OxFFFFFFFF   ;Load R0 with the HEX Values FFFFFFFF
BIC R0, R0, #0xBF    ;This should set bit 7 from my understanding as B is 1011 in hex

When performing the above it places the following value into R0 (0xFFFFFF4F) I wonder why this is?

If i do this bit clear it puts the value 0xFFFFFFBF

MOV R0, #OxFFFFFFFF   ;Load R0 with the HEX Values FFFFFFFF
BIC R0, R0, #00000000000000000000000001000000b

Can anyone help me understand these results?

2

4 Answers

I find it interesting that the assembler (gas) lets you try to mov with more than 8 significant bits without error...it just encodes a mvn for you.

d6008030 <TESTFUN>:
d6008030:   e3e00000    mvn r0, #0
d6008034:   e3c000bf    bic r0, r0, #191    ; 0xbf
d6008038:   e12fff1e    bx  lr

I get 0xFFFFFF40 which is the expected answer.

If you want to set bit 7, then

orr r0,r0,#0x80 ;@ (corrected from 0x70)

Or did you mean you wanted to set bit 6

orr r0,r0,#0x40

if you wanted to strip off all of the bits except bit 6, leaving only bit 6 set.

and r0,r0,#0x40

If you want to leave all but bit 6 set (clear bit 6) (bic=bit clear)

bic r0,r0,#0x40

Or were you trying to do this

mov r0,#0xFFFFFFFF ;@ this is an interesting shortcut
mov r1,#0xFFFFFFBF ;@ might as well keep using it
bic r0,r0,r1

which gives 0x00000040, which is the same as

mov r0,#0xFFFFFFFF ;@ this is an interesting shortcut
and r0,r0,#0x40

except the latter uses less instructions and registers

EDIT

r0,r1,r2, arm tag, etc indicate this is an armv7-a or older question not aarch64 (x0, w0, w1, etc).

but you can see if the compiler will help you figure out what instructions are available for your architecture (arm or other).

unsigned int fun1(unsigned int x)
{
    return (x&(~6));
}
unsigned long long fun2(unsigned long long x)
{
    return (x&(~6));
}

armv4t - armv7a

00000000 <fun1>:
   0:   e3c00006    bic r0, r0, #6
   4:   e12fff1e    bx  lr

00000008 <fun2>:
   8:   e3c00006    bic r0, r0, #6
   c:   e12fff1e    bx  lr

all thumb variants

00000000 <fun1>:
   0:   2306        movs    r3, #6
   2:   4398        bics    r0, r3
   4:   4770        bx  lr
   6:   46c0        nop         ; (mov r8, r8)

00000008 <fun2>:
   8:   2306        movs    r3, #6
   a:   4398        bics    r0, r3
   c:   4770        bx  lr
   e:   46c0        nop         ; (mov r8, r8)

armv7-m (not armv6-m though, some armv8-m but not all)

00000000 <fun1>:
   0:   f020 0006   bic.w   r0, r0, #6
   4:   4770        bx  lr
   6:   bf00        nop

00000008 <fun2>:
   8:   f020 0006   bic.w   r0, r0, #6
   c:   4770        bx  lr
   e:   bf00        nop

aarch64 armv8-a

0000000000000000 <fun1>:
   0:   121d7400    and w0, w0, #0xfffffff9
   4:   d65f03c0    ret
   8:   d503201f    nop
   c:   d503201f    nop

0000000000000010 <fun2>:
  10:   927df400    and x0, x0, #0xfffffffffffffff9
  14:   d65f03c0    ret
2

I think you will see it better if you think about what BIC means/does: BIC Rd, Rn stands for "Rd AND NOT Rn".

So, with your last example:

Rn = 00000000000000000000000001000000b = 0x40
NOT Rn = 0xFFFFFFBF = 11111111111111111111111110111111b
Rd = 0xFFFFFFFF = 11111111111111111111111111111111b
Rd AND NOT Rn = 0xFFFFFFFBF = 11111111111111111111111110111111b

So, with BIC Rd, #0x40 you are clearing bit number 7 of Rd. Same thinking applies to your former example.

Hope this helps.

I test the cases with arm-none-eabi-gcc 4.8.2 on Arduino Due, but the first case is different.

// the results is 0xffffff40, but not 0xffffff4f
mov r2, #0xffffffff
bic r2, r2, #0xbf

The other case is the same.

So the result of the first case is clear just as @Fernando explained above.

operand2 = 0xbf
NOT operand2 = 0xffffff40
r2 = 0xffffffff
r2 AND NOT operand2 = 0xffffff40

The BIC (Bit Clear) instruction performs an AND operation on the bits in Rn with the complements of the corresponding bits in the value of Operand2. You can see it here.

I'm not good at arm instructions but this instruction in your code

BIC R0, R0, #0xBF

#0xBF is #0b10111111, so I think it is clearing bits 0~6, and bit 8 of R0. BIC is bit clearing instruction. To clear bit 7, you can do (set the bit position to 1 if you want to clear the bit)

BIC R0, R0, #0b01000000  ; or
BIC R0, R0, #0x40

I don't think you can 'set' a bit using BIC instruction. BIC is for 'clear'.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.

Share this article
Twitter Facebook Pinterest