Я сделал программу 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 ответ
Использование пробного деления с udiv не лучший алгоритм для FizzBuzz. Проще содержать пару счетчиков; один считает до 3 и сбрасывается, а другой — до 5. Мы можем объединить это в один счетчик (до 15), если захотим.
Диапазон очень ограничен — когда мы достигаем 255, кажется, мы сбрасываем его обратно на 0. Это ограничение должно быть задокументировано!
