代码之家  ›  专栏  ›  技术社区  ›  jameshfisher

从程序集中的文件读取

  •  7
  • jameshfisher  · 技术社区  · 14 年前

    我正在尝试学习汇编——Linux环境中的x86。我能找到的最有用的教程是 Writing A Useful Program With NASM . 我自己设置的任务很简单:读取一个文件并将其写入stdout。

    这就是我所拥有的:

    section  .text              ; declaring our .text segment
      global  _start            ; telling where program execution should start
    
    _start:                     ; this is where code starts getting exec'ed
    
      ; get the filename in ebx
        pop   ebx               ; argc
        pop   ebx               ; argv[0]
        pop   ebx               ; the first real arg, a filename
    
      ; open the file
        mov   eax,  5           ; open(
        mov   ecx,  0           ;   read-only mode
        int   80h               ; );
    
      ; read the file
        mov     eax,  3         ; read(
        mov     ebx,  eax       ;   file_descriptor,
        mov     ecx,  buf       ;   *buf,
        mov     edx,  bufsize   ;   *bufsize
        int     80h             ; );
    
      ; write to STDOUT
        mov     eax,  4         ; write(
        mov     ebx,  1         ;   STDOUT,
      ; mov     ecx,  buf       ;   *buf
        int     80h             ; );
    
      ; exit
        mov   eax,  1           ; exit(
        mov   ebx,  0           ;   0
        int   80h               ; );
    

    这里的一个关键问题是,教程从未提到如何创建缓冲区, bufsize 变量,或者实际上是变量。

    我该怎么做?

    (旁白:经过至少一个小时的搜索,我对学习装配所需的低质量资源深感震惊。当唯一的文件是在网上交易的传闻时,究竟是如何运行计算机的?

    3 回复  |  直到 6 年前
        1
  •  2
  •   guyllo    14 年前

    必须在BSS部分声明缓冲区,并在数据中声明bufsize

    section .data
       bufsize dw      1024
    
    section .bss
       buf     resb    1024
    
        2
  •  8
  •   Borealid    14 年前

    哦,这会很有趣的。

    程序集语言没有变量。这是一个更高级的语言结构。在汇编语言中,如果需要变量,可以自己生成。上坡。两种方式。在雪地里。

    如果需要缓冲区,则必须使用堆栈的某个区域作为缓冲区(在调用适当的堆栈帧设置指令之后),或者使用堆上的某个区域。如果您的堆太小,您将不得不发出一个系统调用指令(另一个int 80h)来请求操作系统提供更多(通过sbrk)。

    另一种选择是学习ELF格式,并在适当的部分创建一个全局变量(我认为是.data)。

    任何这些方法的最终结果都是可以使用的内存位置。但是你唯一真正的“变量”,就像你从现在美妙的C世界习惯的那样,是你的寄存器。而且它们的数量也不多。

    汇编程序可能会帮助您使用有用的宏。阅读汇编程序文档;我不记得它们在我的头上。

    在ASM层面上,生活是艰难的。

        3
  •  0
  •   Viktor Engelmann    8 年前

    调用open之后,文件句柄位于eax中。您正确地将eax移到ebx,在那里read调用将查找它。不幸的是,此时您已经用3(用于读取的系统调用)覆盖了它。