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
相关产品推荐
相关产品推荐

