10

我正在尝试在 Linux 环境中学习汇编——x86。我能找到的最有用的教程是使用 NASM 编写有用的程序。我自己设置的任务很简单:读取文件并将其写入标准输出。

这就是我所拥有的:

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变量或实际上是变量。

我该怎么做呢?

(顺便说一句:经过至少一个小时的搜索,我对学习装配的资源质量低下隐约感到震惊。当唯一的文档是在网上交易的传闻时,任何计算机到底是如何运行的?)

4

3 回答 3

12

哦,这会很有趣。

汇编语言没有变量。这些是更高级别的语言结构。在汇编语言中,如果你想要变量,你自己做。上坡。双向。在雪里。

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

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

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

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

ASM 级别的生活很艰难。

于 2010-07-27T20:44:33.493 回答
5

您必须在 bss 部分声明缓冲区并在数据中声明 bufsize

section .data
   bufsize dw      1024

section .bss
   buf     resb    1024
于 2011-01-19T14:24:25.367 回答
3

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

于 2016-11-08T15:19:24.970 回答