Eliminating zeroes between ones from binary number:
Output
deadbeef
11011110101011011011111011101111
111111111111111111111111
Code
.data
Mask:
.ascii "%x\n\n"
.align 4
varToPrint:
.long 0xdeadbeef
.balign 8
stringToPrint:
.ascii " \n\n"
len = 32
.balign 32
unspacedStringToPrint:
.ascii " \n\n"
len = 32
.balign 32
.text
.globl main
main:
stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, lr} @ save the registers we use to the stack
ldr r3, AddrVarToPrint
ldr r6, [r3]
ldr r3, AddrVarToPrint
str r6, [r3]
bl make_binary_number
bl remove_spaces
bl print_out_result
b exit
print_out_result:
push {r0, r1, r2, r3, r4, lr}
ldr r3, AddrMask
movs r0, r3
ldr r3, AddrVarToPrint
ldr r1, [r3]
bl printf
ldr r3, AddrStringToPrint
movs r0, r3
bl printf
ldr r3, AddrUnspacedStringToPrint
movs r0, r3
bl printf
pop {r0, r1, r2, r3, r4, pc}
make_binary_number:
push {r0, r1, r2, r3, r4, r5, r6, r7, lr}
ldr r3, AddrVarToPrint
ldr r1, [r3]
movs r4, $0
bin_loop:
movs r2, $0x1
lsls r2, r4
movs r6, $31
subs r6, r6, r4
tst r1, r2
beq no_one
ldr r3, AddrStringToPrint
movs r5, $0x31
strb r5, [r3,r6]
b end_bin_loop
no_one:
ldr r3, AddrStringToPrint
movs r5, $0x30
strb r5, [r3,r6]
b end_bin_loop
end_bin_loop:
adds r4, r4,$1
cmp r4, $32
bne bin_loop
pop {r0, r1, r2, r3, r4, r5, r6, r7, pc}
remove_spaces:
push {r0, r1, r2, r3, r4, r5, r6, r7, lr}
ldr r3, AddrVarToPrint
ldr r1, [r3]
ldr r3, AddrUnspacedStringToPrint
movs r5, $0x31
movs r4, $0
movs r7, $0
unspace_loop:
movs r2, $0x1
lsls r2, r4
tst r1, r2
beq end_unspace_loop
strb r5, [r3,r7]
adds r7,r7,$1
end_unspace_loop:
adds r4, r4,$1
cmp r4, $32
bne unspace_loop
pop {r0, r1, r2, r3, r4, r5, r6, r7, pc}
exit:
ldmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, pc} @ restore registers before exit
movs r7, $1 @ set r7 to 1 - the syscall for exit
swi 0 @ then invoke the syscall from linux
AddrMask:
.word Mask
AddrVarToPrint:
.long varToPrint
AddrStringToPrint:
.word stringToPrint
AddrUnspacedStringToPrint:
.word unspacedStringToPrint
Why not count the number of ones?
while (input > 0) {
count += input & 1;
input >>= 1;
}
Resulting int with eliminated zeroes is then (1 << count) – 1.
because counting the number of ones would give you only the number of ones.
given we have 5… that would be 0b0101, the number of ones is 2 (0b0010) which contains zeroes again…
What we want is 0b0011 -> 3
shifting left and oring with 1 for every detected one would be it.
That’s what you get with (1 << count) – 1. Try it out. 🙂
It would be: ( 1 << count )+1
But yes. I get the point.
And then you could reuse the integer2binary string function to show it.
Good idea.