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

将预留数据存入寄存器后入栈、清空数据再出栈打印的问题排查

问题排查与修正

核心问题

你代码的核心错误是混淆了内存地址和数据本身:你推入栈中的是buf的内存地址,而非buf中存储的实际数据。后续清空buf后,弹出的依然是buf的地址,但此时该地址指向的内存内容已经被清空,自然无法打印出预期数据。

错误细节分析

  1. 栈操作逻辑错误:
    执行mov rax, buf时,是把buf的起始地址加载到rax寄存器,而非buf中的数据。随后push rax只是把这个地址推入栈,完全没有实现“将预留数据推入栈”的需求。
  2. 打印逻辑的隐性问题:
    write系统调用要求rsi参数指向要输出的数据内存地址。你弹出栈中的地址到rsi后,该地址指向的buf已经被clearBuf清空,所以输出为空。

修正后的代码

以下是符合需求的修正版本,核心改动是将buf的数据推入栈而非地址,同时调整打印逻辑:

section .text
global _start

_start:
   mov rcx, mesLen
   mov rbx, message
   mov rax, 0
   mov r8, 0

loop1: ; fill buffer
   mov dl, byte [rbx+rax]
   mov byte [buf+r8], dl  ; Use r8 as an index for the buffer
   inc rax
   inc r8
   cmp rax, rcx           ; Compare rax with rcx to check the end of the message
   jl loop1

   ; 将buf中的数据加载到rax,推入栈中(而非buf的地址)
   mov rax, [buf]
   push rax

   ; 清空buf
   call clearBuf

   ; 从栈中弹出数据到rax,存入临时内存用于打印
   pop rax
   mov [temp_buf], rax

   ; 打印弹出的数据
   mov rax, 1
   mov rdi, 1
   mov rsi, temp_buf
   mov rdx, 8
   syscall

   call newLineFunc

   ; 退出程序
   mov rax, 60
   xor rdi, rdi
   syscall

newLineFunc:
   mov rax, 1    
   mov rdi, 1
   mov rsi, newLine
   mov rdx, 1
   syscall
   ret

clearBuf:
   dec r8
   mov byte [buf+r8], 0
   jnz clearBuf
   ret

section .data
   message db "42"
   mesLen equ $-message
   newLine db 10

section .bss
   buf resb 8
   temp_buf resb 8  ; 新增临时内存,用于存储弹出的数据

额外说明

  • clearBuf函数的逻辑是正确的,它会将buf中被写入的字节全部清空为0;
  • 新增temp_buf是因为write系统调用需要读取内存地址的数据,无法直接使用寄存器中的值作为输出源;
  • 如果只需要打印message的内容(比如"42"),可以调整rdx的值为mesLen(即2),避免打印多余的空字节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:43:22