You need to enable JavaScript to run this app. 32位NASM汇编高位取反数组求和结果异常及编译警告问题
优惠活动
大模型
产品
解决方案
定价
更多

32位NASM汇编高位取反数组求和结果异常及编译警告问题

32位NASM汇编数组求和程序修正指南

核心问题定位

1. 求和逻辑错误点

  • 初始版本:求和仅使用8位寄存器bl,10个元素的最大求和结果远超8位寄存器上限,发生溢出;调用printf时仅传入16位bx,和%u要求的32位无符号参数长度不匹配,栈上残留垃圾值导致输出异常。
  • UPD版本:错误将字节数组改为双字数组dd,虽逻辑上可运行,但不符合字节元素的设计需求;未将单字节操作结果零扩展到32位寄存器,直接32位加法会引入非预期值。

2. 编译警告触发原因

当前gcc默认启用PIE(位置无关可执行文件)模式,代码中直接使用绝对地址访问.data段变量(如mov esi, arr)需要修改只读的.text段内容来填充地址,触发两类警告:

  • move to read-only section ".text"
  • DT_TEXTREL is created in PIE

修正方案

代码逻辑修正

  • 恢复字节数组db定义,匹配无符号字节元素的设计需求
  • 用32位寄存器ebx存储求和结果,避免8位加法溢出
  • 每次取字节元素后用movzx将8位值零扩展到32位寄存器,再执行累加
  • 严格匹配printf的cdecl调用约定:参数从右往左压栈,调用后清理栈空间

编译警告消除

二选一即可:

  • 编译链接时关闭PIE模式(最简单):使用gcc -m32 -no-pie test.o命令
  • 编写位置无关代码,适配PIE要求:访问全局变量时从GOT表读取地址,避免在.text段写入绝对地址

修正后可运行代码

; 编译执行命令:nasm -felf32 test.asm && gcc -m32 -no-pie test.o && ./a.out
section .rodata
        msg db 'Sum: %u', 10, 0  ; 只读格式串放到.rodata段

section .data
        arr db 0, 254, 126, 126, 126, 126, 126, 126, 126, 126
        arr_len equ 10

section .text
        global main
        extern printf

main:
        push ebp
        mov ebp, esp  ; 建立标准C栈帧,保证调用规范
        
        mov esi, arr
        mov ecx, arr_len
        xor ebx, ebx  ; ebx存储求和结果,初始为0

sum_loop:
        mov al, byte [esi]
        test al, 10000000b  ; 检测字节最高位
        jz add_sum
        not al  ; 最高位为1则对该字节取反
add_sum:
        movzx eax, al  ; 将8位值零扩展到32位寄存器,避免溢出
        add ebx, eax
        inc esi
        dec ecx
        jnz sum_loop

        ; 调用printf("Sum: %u\n", sum)
        push ebx       ; 第二个参数:求和结果
        push msg       ; 第一个参数:格式串地址
        call printf
        add esp, 8     ; 清理栈上参数,保持栈平衡

        xor eax, eax   ; main返回值为0
        pop ebp
        ret

关键说明

注:原提问中预期结果计算存在小误差,8个126的累加值为1008,加上254取反后的1,最终正确求和结果为1009。

  • 若需保留PIE模式(不使用-no-pie参数),可将代码中访问数组的指令改为mov esi, arr wrt ..got,通过全局偏移表读取变量地址,生成位置无关代码,同样可以消除编译警告。
  • 代码移除了未使用的nextline变量、print宏,减少冗余。
    内容的提问来源于stack exchange,提问作者Alex Breshniv
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 02:36:06