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

汇编记录程序问题:最长姓名长度计算错误及numpeople值异常

汇编程序错误分析与修复

问题1:numpeople值为4而非预期的6

原因

代码定义PERSON_RECORD_SIZE为72字节,对应32字节姓名区+5个8字节字段(共40字节),但实际每条记录的姓名.ascii字符串长度不足32字节,且未填充剩余空间,导致单条记录实际长度小于72字节。总记录长度endpeople - people除以72后,得到错误的结果4,而非正确的6。

修复方法

在每个姓名字符串后填充空白字节,确保姓名区占满32字节:

people:
    .ascii "Gilbert Keith\0"
    .space 32 - (.-people)  # 填充至32字节长度
    .quad 200, 10, 2, 74, 20
    .ascii "Jonathan Barlett\0"
    .space 32 - (.-people)
    .quad 280, 12, 2, 72, 44
    .ascii "Gilbert Keith Chesterfield\0"
    .space 32 - (.-people)
    .quad 150, 8, 1, 68, 30
    .ascii "Tommy Aquinas\0"
    .space 32 - (.-people)
    .quad 250, 14, 3, 75, 24
    .ascii "Isaac Newn\0"
    .space 32 - (.-people)
    .quad 250, 10, 4, 70, 11
    .ascii "Gregory Mend\0"
    .space 32 - (.-people)
    .quad 180, 11, 5, 69, 65
endpeople:

.space N指令会填充N个空白字节,.-people计算当前位置与people起始地址的偏移,用32减去该值即可补全姓名区至32字节,确保每条记录总长度为72字节。此时(endpeople - people)/PERSON_RECORD_SIZE会正确计算为6。

问题2:程序仅返回第一个姓名的长度13

原因

由于每条记录实际长度未达到72字节,执行addq $PERSON_RECORD_SIZE, %rbx后,rbx会跳过后续有效数据,指向错误位置。读取该位置字节时直接遇到\0,导致后续记录的姓名长度被计算为0,无法更新最长长度寄存器%rdi。

修复方法

修复记录长度对齐问题后,rbx的偏移会正确指向每条记录的起始地址,程序就能正常遍历所有6条记录并统计最长姓名长度。原代码中的寻址逻辑NAME_OFFSET(%rbx, %rdx, 1)等价于%rbx + %rdx + NAME_OFFSET,逻辑本身无误,只需确保记录长度符合定义即可。

完整修复后的代码

.section .data

.globl people, numpeople
numpeople:
    .quad (endpeople - people)/PERSON_RECORD_SIZE
people:
    .ascii "Gilbert Keith\0"
    .space 32 - (.-people)
    .quad 200, 10, 2, 74, 20
    .ascii "Jonathan Barlett\0"
    .space 32 - (.-people)
    .quad 280, 12, 2, 72, 44
    .ascii "Gilbert Keith Chesterfield\0"
    .space 32 - (.-people)
    .quad 150, 8, 1, 68, 30
    .ascii "Tommy Aquinas\0"
    .space 32 - (.-people)
    .quad 250, 14, 3, 75, 24
    .ascii "Isaac Newn\0"
    .space 32 - (.-people)
    .quad 250, 10, 4, 70, 11
    .ascii "Gregory Mend\0"
    .space 32 - (.-people)
    .quad 180, 11, 5, 69, 65
endpeople:

.globl NAME_OFFSET, WEIGHT_OFFSET, SHOE_OFFSET
.globl HAIR_OFFSET, HEIGHT_OFFSET, AGE_OFFSET
.equ NAME_OFFSET, 0
.equ WEIGHT_OFFSET, 32
.equ SHOE_OFFSET, 40
.equ HAIR_OFFSET, 48
.equ HEIGHT_OFFSET, 56
.equ AGE_OFFSET, 64

.globl PERSON_RECORD_SIZE
.equ PERSON_RECORD_SIZE, 72
.globl _start

.section .text

_start:
    leaq people, %rbx

    movq numpeople, %rcx

    movq $0, %rdi

    movq $0, %rdx

    cmpq $0, %rcx
    je finish

mainloop:
    movb NAME_OFFSET(%rbx, %rdx, 1), %al

    cmpb $0, %al
    je nextstring

    incq %rdx

    jmp mainloop

nextstring:
    cmpq %rdi, %rdx
    cmovgq %rdx, %rdi

    addq $PERSON_RECORD_SIZE, %rbx

    movq $0, %rdx

    loopq mainloop

finish:
    movq $60, %rax
    syscall

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 08:47:14