ARM assembly

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

4 thoughts on “ARM assembly”

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

    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.

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

Leave a Reply

Your email address will not be published. Required fields are marked *