本文介绍了X86 从 stdin 读取并写入 stdout 而不引用标准库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 X86 汇编语言的初学者.我知道如何使用内置函数从 stdin 读取和写入 stdout,但我不确定如何使用普通的汇编代码(即操作寄存器和利用系统调用)来做到这一点.

I'm a beginner in X86 assembly language. I know how to read from stdin and write to stdout using build-in functions, but I'm not sure how to do it with plain assembly code(i.e. manipulating registers and taking advantage of system calls).

#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;
}

这是我写的 C 代码,首先从标准输入(由数字 0 表示)读取然后写入标准输出(由数字 1 表示).有人能帮我把它转换成普通的汇编代码吗(请不要调用读取"和调用写入")?

This is the C code I wrote to first read from the standard input (represented by number 0) then write to the standard output (represented by number 1). Can anybody help me to convert it into plain assembly code(NO "call read" & "call write" please)?

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

The syntax doesn't matter, but 32-bit AT&T is preferred since I have been using it:) Thanks in advance!

推荐答案

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

The system calls should be well-documented for whatever operating system you're using. For example, see the Linux ones here.

因此,在您的情况下,要从标准输入读取,您将加载 eax 与 3,ebx 与描述符 0ecx 为缓冲区地址,edx 为长度.

So, in your case, to read from standard input, you would load eax with 3, ebx with the descriptor 0, ecx with the buffer address and edx with the length.

然后使用 int 0x80(32 位 Linux)或 syscall(64 位模式)调用系统调用接口,具体取决于您的平台.或者您可以使用 sysenter 进行优化的 32 位系统调用,但它需要其他设置,不建议直接使用.请参阅权威指南Linux 系统调用了解更多详情.

Then call the syscall interface with int 0x80 (32-bit Linux) or syscall (64-bit mode), depending on your platform. Or you can use sysenter for optimized 32-bit system calls, but it requires other setup and using it directly is not recommended. See The Definitive Guide to Linux System Calls for more detail.

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

The eax register will then (on return from the read syscall) contain the number of bytes read on success, or an error indication otherwise.

我手边没有 Linux 机器,但它应该是这样的:

I don't have a Linux box handy but it would be something like:

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)

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

That would be the basic structure of your loop. As stated, this was written from memory so it may need some debugging, I may even have some of the mnemonics wrong. But that should hopefully be a start.

这篇关于X86 从 stdin 读取并写入 stdout 而不引用标准库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 19:29