You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARM macOS汇编程序w4寄存器结果输出异常排查

ARM64 macOS汇编:数组大于指定值元素之和输出错误修复

问题分析

你的程序输出4294967294是因为两个核心问题:

  1. 求和逻辑完全反转:你需要累加大于crit的元素,但当前代码的条件判断是当crit <= 当前元素时跳过相加,实际只累加了小于crit的元素。
  2. 32位到64位的符号扩展错误:w4是32位有符号寄存器,用mov x1, x4会把它零扩展成64位无符号数,导致负数-2被转换成4294967294(0xFFFFFFFE)。

修复步骤

1. 修正求和逻辑

把cmp w1, w5后的ble skipsum改成bge skipsum:

  • 原逻辑:ble skipsum → 当crit <= 当前元素时跳过相加(只加小于crit的)
  • 修正后:bge skipsum → 当crit >= 当前元素时跳过相加(只加大于crit的)

数组中大于3的元素是4和9,总和为4+9=13,这才是预期结果。

2. 修复符号扩展问题

把mov x1, x4改成sxtw x1, w4,这样32位有符号数会正确扩展成64位有符号数,避免负数被错误转换。

3. 优化字符串输出长度(可选)

当前write调用固定写20字节,会把buffer里的垃圾数据也输出(比如末尾的%)。可以在int_to_str函数返回字符串起始地址后,计算有效长度再输出,避免冗余内容。

完整修复后的代码

.data
crit: .word 3
numsl: .word 6
nums: .word 1, 1, 1, 4, -5, 9
buffer: .space 20  // Буфер для хранения строки числа

.text
.global _start

_start:
    // Загрузить значение crit
    adrp x0, crit@PAGE
    add x0, x0, crit@PAGEOFF
    ldr w1, [x0]

    // Загрузить значение numsl
    adrp x2, numsl@PAGE
    add x2, x2, numsl@PAGEOFF
    ldr w2, [x2]

    // Загрузить адрес nums
    adrp x3, nums@PAGE
    add x3, x3, nums@PAGEOFF

    // Инициализировать сумму (w4) нулем
    mov w4, 0

sumiteration:
    ldr w5, [x3], 4         // Загрузить значение из nums и увеличить x3 на 4
    cmp w1, w5              // Сравнить crit с текущим элементом nums
    bge skipsum             // 修正:Если crit >= текущий элемент, перейти к skipsum (只加大于crit的)
    add w4, w4, w5          // Добавить текущий элемент к сумме

skipsum:
    subs w2, w2, 1          // Уменьшить счетчик элементов (w2) на 1
    bne sumiteration        // Если счетчик не равен нулю, повторить цикл

    // Преобразование числа в строку
    adrp x0, buffer@PAGE
    add x0, x0, buffer@PAGEOFF
    sxtw x1, w4             // 修正:符号扩展32位w4到64位x1
    bl int_to_str

    // Вывод числа - 计算有效长度
    mov x3, x0              // x3 = 字符串起始地址
    adrp x4, buffer@PAGE
    add x4, x4, buffer@PAGEOFF
    add x4, x4, #20         // x4 = buffer末尾地址
    sub x2, x4, x3          // x2 = 有效字符串长度

    mov x0, #1              // File descriptor 1 (stdout)
    mov x1, x3              // 字符串起始地址
    mov x16, #4             // Номер системного вызова для write в macOS
    svc 0                   // Вызвать системный вызов

    // Завершение программы
    mov x0, #0              // Return code 0
    mov x16, #1             // Номер системного вызова для exit в macOS
    svc 0                   // Вызвать системный вызов

// Простой алгоритм преобразования числа в строку
int_to_str:
    // x0 - адрес буфера
    // x1 - число для преобразования
    mov x2, x1              // Копировать число в x2
    mov x3, #10             // Делитель
    add x0, x0, #19         // Начать с конца буфера
    mov w4, #'0'            // ASCII '0'
    mov w5, 0               // Флаг для отрицательных чисел

    cmp x1, 0
    bge convert_loop        // Если число неотрицательное, пропустить обработку
    neg x2, x1              // Взять абсолютное значение числа
    mov w5, 1               // Установить флаг для отрицательных чисел

convert_loop:
    udiv x6, x2, x3         // x6 = x2 / 10
    msub x7, x6, x3, x2     // x7 = x2 - x6 * 10 (остаток)
    add x7, x7, x4          // Преобразовать остаток в символ
    strb w7, [x0], #-1      // Сохранить символ и перейти назад в буфере
    mov x2, x6              // x2 = x6
    cbz x2, end_conversion  // Если x2 == 0, закончить

    b convert_loop

end_conversion:
    cbz w5, skip_minus      // Если число не было отрицательным, пропустить
    mov w6, #'-'            // ASCII '-'
    strb w6, [x0], #-1      // Сохранить знак минус

skip_minus:
    add x0, x0, #1          // Переместить указатель на начало строки
    ret

验证结果

用原编译命令重新编译运行后,输出应为13,符合预期。

内容的提问来源于stack exchange,提问作者Andrey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 06:43:15