I've been playing with ARMv8 Assembly and NCurses the past couple days with decent success. The following code does exactly what it is supposed to. Centers a window and draws an 'o' inside.
.global main
.section .text
.align 2
main:
ldr x0, =termtitle
bl printf
bl initscr
mov x0, #0
bl curs_set
bl refresh
adrp x9, court
add x9, x9, :lo12:court
mov x0, #1
mov x1, #0x5413
ldr x2, =termsize
mov x8, #29
svc #0
ldr x19,=termsize
mov x0, #10
mov x1, #30
ldr w4, [x19,#0]
mov x5, #2
udiv w2, w4, w5
sub x2, x2, #5
ldr w4, [x19,#2]
mov x5, #2
udiv w3, w4, w5
sub x3, x3, #15
bl newwin
str x0, [x9]
ldr x0, [x9]
sub sp, sp, #16
str x0, [sp]
mov x1, #0
mov x2, #0
bl box
adrp x9, court
add x9, x9, :lo12:court
ldr x0, [x9]
mov x1, #5
mov x2, #5
ldr x3, =prototype
bl mvwprintw
ldr x0, [sp]
add sp, sp, #16
bl wrefresh
bl getch
bl endwin
mov x8, 93
mov x0, 0
svc 0
.section .data
termsize: .skip 4
termtitle: .asciz "\033]0;ARMv8 - Ncurses Bouncing Ball\007"
court: .quad 0
ball:
.byte 0
.byte 0
.byte 0x4F
prototype: .asciz "o"
The problem comes as I try to tidy things up. When I place the following syscall into its own subroutine:
GetTermSize:
mov x0, #1
mov x1, #0x5413
ldr x2, =termsize
mov x8, #29
svc #0
And then attempt to call it with bl from its original location under main:, my program declares Illegal Instruction.
You forgot to return to the caller in GetTermSize
. Execution will thus continue with whatever instruction follows svc #0
. To fix this problem, add a ret
instruction:
GetTermSize:
mov x0, #1
mov x1, #0x5413
ldr x2, =termsize
mov x8, #29
svc #0
ret
Note also that your main
function currently does not save the link register x30
anywhere. You'll not be able to return from main
. If you want to do so, make sure to save the link register on the stack and restore it before you return.