从汇编中的文件读取
我正在尝试在 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 变量或实际上的变量。
我该怎么做?
(顺便说一句:经过至少一个小时的搜索,我对学习汇编的资源质量低下感到震惊。当唯一的文档是网上交易的道听途说时,计算机到底如何运行?)
I'm trying to learn assembly -- x86 in a Linux environment. The most useful tutorial I can find is Writing A Useful Program With NASM. The task I'm setting myself is simple: read a file and write it to stdout.
This is what I have:
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 ; );
A crucial problem here is that the tutorial never mentions how to create a buffer, the bufsize
variable, or indeed variables at all.
How do I do this?
(An aside: after at least an hour of searching, I'm vaguely appalled at the low quality of resources for learning assembly. How on earth does any computer run when the only documentation is the hearsay traded on the 'net?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
哦,这会很有趣。
汇编语言没有变量。这些是更高级的语言构造。在汇编语言中,如果你想要变量,你可以自己创建它们。上坡。两种方式。在雪地里。
如果您想要一个缓冲区,则必须使用堆栈的某些区域作为缓冲区(在调用适当的堆栈帧设置指令之后),或者使用堆上的某些区域。如果你的堆太小,你必须创建一条 SYSCALL 指令(另一个 INT 80h)来请求操作系统提供更多(通过 sbrk)。
另一种选择是了解 ELF 格式并在适当的部分创建一个全局变量(我认为是 .data)。
这些方法的最终结果都是您可以使用的内存位置。但你唯一真正的“变量”就像你在现在看起来很美好的 C 世界中所习惯的那样,是你的寄存器。而且数量并不多。
汇编器可能会帮助您使用有用的宏。阅读汇编器文档;我不记得他们了。
ASM 级别的生活很艰难。
Ohh, this is going to be fun.
Assembly language doesn't have variables. Those are a higher-level language construct. In assembly language, if you want variables, you make them yourself. Uphill. Both ways. In the snow.
If you want a buffer, you're going to have to either use some region of your stack as the buffer (after calling the appropriate stack-frame-setup instructions), or use some region on the heap. If your heap is too small, you'll have to make a SYSCALL instruction (another INT 80h) to beg the operating system for more (via sbrk).
Another alternative is to learn about the ELF format and create a global variable in the appropriate section (I think it's .data).
The end result of any of these methods is a memory location you can use. But your only real "variables" like you're used to from the now-wonderful-seeming world of C are your registers. And there aren't very many of them.
The assembler might help you out with useful macros. Read the assembler documentation; I don't remember them off the top of my head.
Life is tough down there at the ASM level.
您必须在 bss 部分声明缓冲区并在 data 部分声明 bufsize
you must declare your buffer in bss section and the bufsize in data
调用 open 后,文件句柄位于 eax 中。您正确地将 eax 移动到 ebx,read 调用将在其中查找它。不幸的是,此时您已经用 3(用于读取的系统调用)覆盖了它。
After the call to open, the file handle is in eax. You rightfully move eax it to ebx, where the call to read will look for it. Unfortunately, at this point you have already overwritten it with 3, the syscall for reading.