Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BIC Instruction

Tags:

assembly

arm

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?

like image 923
mitchnufc Avatar asked Feb 23 '12 19:02

mitchnufc


2 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
like image 163
old_timer Avatar answered Oct 05 '22 12:10

old_timer


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.

like image 34
Fernando Avatar answered Oct 05 '22 13:10

Fernando