X86 从 stdin 读取并写入 stdout,无需引用标准库

Met*_*ite 2 x86 stdin stdout system-calls att

我是 X86 汇编语言的初学者。我知道如何使用内置函数从标准输入读取数据并写入标准输出,但我不确定如何使用简单的汇编代码(即操作寄存器和利用系统调用)来做到这一点。

#include <stdio.h>
#include <unistd.h>

int main(){  /* copy input to output */
    char buf[BUFSIZ];
    int n;

    while ((n = read(0, buf, BUFSIZ)) > 0)
        write(1, buf, n);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我编写的 C 代码,首先从标准输入(由数字 0 表示)读取,然后写入标准输出(由数字 1 表示)。有人可以帮我将其转换为纯汇编代码(请不要“调用读取”和“调用写入”)吗?

语法并不重要,但 32 位 AT&T 是首选,因为我一直在使用它:) 提前致谢!

pax*_*blo 5

对于您使用的任何操作系统,系统调用都应该有详细的记录。例如,请参阅此处的 Linux 。

因此,在您的情况下,要从标准输入读取,您将加载eax3、ebx描述符0ecx缓冲区地址和edx长度。

然后根据您的平台,使用int 0x80(32 位 Linux)或syscall(64 位模式)调用系统调用接口。或者您可以用于sysenter优化的32位系统调用,但它需要其他设置,不建议直接使用它。有关更多详细信息,请参阅《Linux 系统调用权威指南》 。

然后,寄存器eax将(从read系统调用返回时)包含成功读取的字节数,否则包含错误指示。

我手边没有 Linux 盒子,但它会是这样的:

section .bss
   buf      resb 1                  ; 1-byte buffer

section .text
    global _start

_start:

loop1:   mov  edx, 1             ; max length
         mov  ecx, buf           ; buffer
         mov  ebx, 0             ; stdin
         mov  eax, 3             ; sys_read
         int  80h

         cmp  eax, 0             ; end loop if read <= 0
         jle  lpend1

         mov  edx, eax           ; length
         mov  ecx, buf           ; buffer
         mov  ebx, 1             ; stdout
         mov  eax, 4             ; sys_write
         int  80h

         jmp  loop1              ; go back for more
lpend1: 
         mov    eax, 1
         mov    ebx, 0
         int    80h              ; _exit(0)
Run Code Online (Sandbox Code Playgroud)

这将是循环的基本结构。如前所述,这是从内存中编写的,因此可能需要一些调试,我什至可能有一些助记符错误。但这应该是一个开始。