【问题标题】:Assebmly x68-64 reads out png file wrong [duplicate]程序集 x68-64 读出 png 文件错误 [重复]
【发布时间】:2022-12-05 04:25:34
【问题描述】:

我正在尝试使用以下代码读取带有程序集的 png 文件:

SECTION .bss            ; Section containing uninitialized data
InBufLen: equ 3
InBuf:         resb InBufLen

SECTION .text           ; Section containing code

global _start           ; Linker needs this to find the entry point!

_start:

    call read

read: ; read chunk from stdin to InBuf
    mov rax, 0                      ; sys_read
    mov rdi, 0                      ; file descriptor: stdin
    mov rsi, InBuf                  ; destination buffer
    mov rdx, InBufLen               ; maximum # of bytes to read
    syscall

; check number of bytes read
    cmp rax, 0                      ; did we receive any bytes?
    je exit; if not: exit the program

    xor r10, r10
    mov r10, rax                    ; save # of bytes read
    xor r11, r11
    xor rax, rax

process:
    mov eax, [InBuf + r11]

xxd 说我的代码应该读出 0x89504e 作为前 3 个字节,但是在 gdb 中调试时,它说前三个字节是 0x4e5089。我想我读错了数据。

【问题讨论】:

  • 您如何显示 gdb 中的字节?看起来它可能将它们解释为小端格式的数值。
  • x86 是小端; EAX 值为 0x004e5089 表示内存中的字节为 89 50 4e 00。高字节恰好为零,因为 BSS 中没有其他内容在它之后,但通常你不应该读到你保留的东西的末尾,除非你知道接下来会发生什么并且准备忽略那个高位垃圾。
  • 此外,您不需要在写入之前对寄存器进行异或归零。 mov r10d, eax复制尺寸就好了。您也不需要在 mov eax, [InBuf + r11] 之前将 RAX 归零;将 EAX 零扩展写入 RAX。

标签: assembly png x86-64


【解决方案1】:

看起来您正在使用 x86-64 指令集从输入缓冲区读取。在此指令集中,mov 指令有两个操作数:目标和源。目标在 , 的左侧,源在右侧。

在您的代码中,您使用 mov 指令从输入缓冲区读取数据,但操作数的顺序错误。这意味着您正在从输入缓冲区读取并将结果存储在 eax 寄存器中,而不是相反。

要解决此问题,您需要将 mov eax, [InBuf + r11] 行更改为 mov [InBuf + r11], eax。这将读取输入缓冲区中给定地址处的值,并将其存储在 eax 寄存器中,如预期的那样。

还值得注意的是,在 x86-64 指令集中,eax 寄存器与 rax 寄存器不同。 eax 寄存器是 rax 寄存器的低 32 位,因此如果您在代码中使用 eax,则需要确保只存储适合 rax 寄存器低 32 位的值。否则,您的代码可能会遇到问题。

【讨论】:

  • mov [InBuf + r11], eax 将是一个存储(从 eax 到内存),正如您在第一段中解释的那样:目的地在 Intel 语法中位于左侧,就像 NASM 使用的那样。如果他们的代码实际上在应该加载的时候存储,EAX 就会在那里为零,因为他们只是将前一条指令中的整个 RAX 归零。
猜你喜欢
  • 2014-11-16
  • 2016-08-15
  • 2016-04-04
  • 2013-07-17
  • 2017-05-27
  • 1970-01-01
  • 2023-01-11
  • 2020-08-13
相关资源
最近更新 更多