FizzBuzz в arm64

Я сделал программу FizzBuzz на arm64; Я распечатываю значения в шестнадцатеричном формате, а не в десятичном. Это была первая созданная мной программа для arm64, и я ищу совета, как я могу ее улучшить.

Код для распечатки регистров был взят из учебника: Программирование на 64-битном языке сборки ARM: разработка одноплатных компьютеров для Raspberry Pi и мобильных устройств пользователя Стивен Смит.

//
// FizzBuzz
//

.global _start

// 
// x0-x2 & x8 - linux shit
// x3 - loop counter
// x4 - variable
// x5 - dividend
// x6 - divisor

_start:     mov x3, #100    // instantiate x3
    
loop:       subs    x4, x3, #101    // subtract x3 by 101
        mvn x4, x4      // multiply x4 by -1 (bug: x4 is getting set to 0)
        add x4, x4, #1
        // if x4 % 15 == 0 then goto divby15
        // r = j - qk (took this divisibility checker from number theory)
        mov x6, #15
        udiv    x5, x4, x6
        msub    x5, x5, x6, x4
        cmp x5, #0
        b.eq    divby15
        // if x4 % 3 == 0 then goto divby3
        mov x6, #3
        udiv    x5, x4, x6
        msub    x5, x5, x6, x4
        cmp x5, #0
        b.eq    divby3
        // if x4 % 5 == 0 then goto divby5
        mov x6, #5
        udiv    x5, x4, x6
        msub    x5, x5, x6, x4
        cmp x5, #0
        b.eq    divby5
        // print x

// 
// Prints the register value
//
// Registers:
// x1 - byte address
// w5 - loop index
// w6 - current character
// x7 - register to print
// x8 - linux shit
//
        mov x7, x4

        ldr x1, =hexstr
        add x1, x1, #3
        mov w5, #2

loop2:      and w6, w7, #0xF
        cmp w6, #10
        b.ge    letter
        add w6, w6, #'0'
        b   cont

letter:     add w6, w6, #('A'-10)

cont:       strb    w6, [x1]
        sub x1, x1, #1
        lsr x7, x4, #4
        subs    w5, w5, #1
        b.ne    loop2

        mov x0, #1
        ldr x1, =hexstr
        mov x2, #6
        mov x8, #64
        svc 0

/////////////////////////////////////////////
/////////////////////////////////////////////
/////////////////////////////////////////////

        // repeat if x3 isn't equal to 0
inc:        sub x3, x3, #1
        cmp x3, #0
        b.ne    loop
        b   end

divby3:     mov x0, #1
        ldr x1, =fizz
        mov x2, #5
        mov x8, #64
        svc 0
        b   inc

divby5:     mov x0, #1
        ldr x1, =buzz
        mov x2, #5
        mov x8, #64
        svc 0
        b   inc

divby15:    mov x0, #1
        ldr x1, =fizzbuzz
        mov x2, #9
        mov x8, #64
        svc 0
        b   inc

end:        mov x0, #0
        mov x8, #93
        svc 0

.data
fizz:       .ascii  "fizzn"
buzz:       .ascii  "buzzn"
fizzbuzz:   .ascii  "fizzbuzzn"
hexstr:     .ascii  "0xFFn"

1 ответ
1

Использование пробного деления с udiv не лучший алгоритм для FizzBuzz. Проще содержать пару счетчиков; один считает до 3 и сбрасывается, а другой — до 5. Мы можем объединить это в один счетчик (до 15), если захотим.

Диапазон очень ограничен — когда мы достигаем 255, кажется, мы сбрасываем его обратно на 0. Это ограничение должно быть задокументировано!

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *