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?
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With