X86 read from stdin and write to stdout without referring the standard library

廉价感情. 提交于 2020-12-30 03:55:33

问题


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

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)?

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


回答1:


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

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.

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.

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

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.



来源:https://stackoverflow.com/questions/27262332/x86-read-from-stdin-and-write-to-stdout-without-referring-the-standard-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!