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

X86汇编结构体指针异常:无法正确存储或返回数据

问题排查与修正方案

你的核心问题大概率出在结构体存储/指针移动逻辑错误,或是readInt调用后的寄存器处理、结构体偏移定义上,以下是针对性的排查和修正步骤:

1. 确认结构体定义的正确性

确保Point结构体的偏移量符合X86内存布局,比如两个4字节整数的结构体应定义为:

Point struct
    x dd ?  ; 偏移地址0
    y dd ?  ; 偏移地址4
Point ends

如果偏移定义错误(比如y的偏移不是4),会导致数据存到无效内存位置,输出自然为空。

2. 修正输入存储流程

你提到用mov [esi + Point.x], eax和mov [esi + Point.y], eax存储,但要注意两个关键细节:

  • 必须两次调用readInt:第一次读x存入[esi+Point.x],第二次读y存入[esi+Point.y],不能复用同一个eax值(若eax被其他操作修改,会导致数据错误)。
  • 每组数据存储完成后,必须将esi递增整个Point结构体的大小(8字节,两个dd各占4字节),否则下一组数据会覆盖当前组,或存到数组外的无效内存。

正确的读取循环示例:

.data
    arr Point 5 dup(<>)  ; 预分配5个Point的数组
    prompt_x db "Enter x: ", 0
    prompt_y db "Enter y: ", 0
.code
    mov esi, offset arr  ; esi指向数组第一个元素
    mov ecx, 5           ; 循环计数器,控制5组数据
read_loop:
    ; 读取x
    mov edx, prompt_x
    call printString
    call readInt         ; eax = 用户输入的x
    mov [esi + Point.x], eax
    ; 读取y
    mov edx, prompt_y
    call printString
    call readInt         ; eax = 用户输入的y
    mov [esi + Point.y], eax
    ; 移动到下一个Point元素
    add esi, sizeof Point
    dec ecx
    jnz read_loop

3. 验证输出逻辑

输出时需要将esi重置为数组起始位置,再逐个读取元素的x和y:

.data
    comma_str db ", ", 0
.code
    mov esi, offset arr
    mov ecx, 5
print_loop:
    ; 输出x
    mov eax, [esi + Point.x]
    call printInt
    ; 输出分隔符
    mov edx, offset comma_str
    call printString
    ; 输出y
    mov eax, [esi + Point.y]
    call printInt
    call printNewLine  ; 换行
    ; 移动到下一个元素
    add esi, sizeof Point
    dec ecx
    jnz print_loop

4. 额外排查点

  • 检查readInt实现:确认它确实将输入整数存入eax,且没有破坏esi等寄存器(若readInt修改了esi,需在调用前push esi,调用后pop esi恢复)。
  • 调试寄存器值:在存储前临时输出eax,确认readInt确实读取到了用户输入的整数,排除输入函数本身的问题。
  • 检查内存分配:确认数组arr在数据段中分配了足够空间,5 dup(<>)会初始化5个空Point结构体,总空间为40字节,避免越界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 10:02:01