GNU/Linux xterm-256color zsh 137 views

.section .data
msg:        .asciz "Area: "
buffer_x:   .space 8
buffer_y:   .space 8
buffer_r:   .space 8
result_buf: .space 16
newline:    .asciz "\n"
pi_fixed:   .quad 31416      // π ≈ 3.1416 × 10000
escala:     .quad 10000      // divisor de punto fijo

.section .text
.global _start

_start:
    // -----------------------
    // Leer x
    // -----------------------
    mov x0, #0
    ldr x1, =buffer_x
    mov x2, #8
    mov x8, #63
    svc 0
    ldr x1, =buffer_x
    bl ascii_to_int
    // Descartar valor de x

    // -----------------------
    // Leer y
    // -----------------------
    mov x0, #0
    ldr x1, =buffer_y
    mov x2, #8
    mov x8, #63
    svc 0
    ldr x1, =buffer_y
    bl ascii_to_int
    // Descartar valor de y

    // -----------------------
    // Leer radio r
    // -----------------------
    mov x0, #0
    ldr x1, =buffer_r
    mov x2, #8
    mov x8, #63
    svc 0
    ldr x1, =buffer_r
    bl ascii_to_int
    mov x20, x0         // x20 = r

    // -----------------------
    // Calcular área = π·r²
    // -----------------------
    mul x21, x20, x20   // r²
    ldr x22, =pi_fixed
    ldr x22, [x22]      // π * 10000
    mul x23, x21, x22   // r² * π_fixed

    ldr x24, =escala
    ldr x24, [x24]
    udiv x25, x23, x24  // resultado entero en x25

    // -----------------------
    // Convertir resultado a texto ASCII
    // -----------------------
    mov x0, x25
    ldr x1, =result_buf
    bl int_to_ascii

    // Mostrar mensaje
    mov x0, #1
    ldr x1, =msg
    mov x2, #6
    mov x8, #64
    svc 0

    // Mostrar número
    mov x0, #1
    ldr x1, =result_buf
    mov x2, #8
    mov x8, #64
    svc 0

    // Salto de línea
    mov x0, #1
    ldr x1, =newline
    mov x2, #1
    mov x8, #64
    svc 0

    // Salida
    mov x0, #0
    mov x8, #93
    svc 0

// ------------------------------------------------------------
// ascii_to_int: convierte texto ASCII a número
// Entrada: x1 = buffer
// Salida:  x0 = número entero (x0)
// ------------------------------------------------------------
ascii_to_int:
    mov x0, #0
    mov x2, #0
    mov x3, #10

parse_loop:
    add x4, x1, x2
    ldrb w5, [x4]
    cmp w5, #'0'
    blt end_parse
    cmp w5, #'9'
    bgt end_parse
    sub w5, w5, #'0'
    mul x0, x0, x3
    uxtw x6, w5           // ✅ Extensión segura
    add x0, x0, x6        // ✅ No mezcla de registros
    add x2, x2, #1
    b parse_loop

end_parse:
    ret

// ------------------------------------------------------------
// int_to_ascii: convierte entero positivo a texto ASCII
// Entrada: x0 = número, x1 = buffer destino
// ------------------------------------------------------------
int_to_ascii:
    mov x2, #10
    mov x3, x1
    mov x4, #0

convert_loop:
    udiv x5, x0, x2
    msub x6, x5, x2, x0
    add x6, x6, #'0'
    strb w6, [x1], #1
    add x4, x4, #1
    mov x0, x5
    cbz x0, reverse_ascii
    b convert_loop

reverse_ascii:
    sub x1, x1, x4
    mov x5, #0
rev_loop:
    cmp x5, x4
    bge done_ascii
    sub x4, x4, #1
    ldrb w6, [x1, x5]
    ldrb w7, [x1, x4]
    strb w7, [x1, x5]
    strb w6, [x1, x4]
    add x5, x5, #1
    b rev_loop

done_ascii:
    ret