assemblyarmv8

Creating a Sub-Routine results in illegal instruction


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.


Solution

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