mitchnufc
mitchnufc

Reputation: 309

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?

Upvotes: 7

Views: 32688

Answers (4)

Chan Kim
Chan Kim

Reputation: 5989

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'.

Upvotes: 0

old_timer
old_timer

Reputation: 71566

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

Upvotes: 8

LuoPeng
LuoPeng

Reputation: 11

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.

Upvotes: 1

Fernando
Fernando

Reputation: 386

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.

Upvotes: 5

Related Questions