Linux NASM,读取文件并打印内容

Linux NASM,读取文件并打印内容,linux,assembly,nasm,Linux,Assembly,Nasm,我在NASM(linux版)中有一段代码,它本应打开一个现有文件,读取并在屏幕上打印内容,但不起作用,有人能告诉我我做错了什么吗?(hello.txt是文件名) 这是错误的。松开文件周围的方括号。您传递的是文件名,而不是指向文件名的指针 mov ebx, file ; const char *filename mov eax, 5 mov ecx, 0 int 80h 我在这里看到很多错误,顺序如下: mov ebx, [file] ; name of the file

我在NASM(linux版)中有一段代码,它本应打开一个现有文件,读取并在屏幕上打印内容,但不起作用,有人能告诉我我做错了什么吗?(
hello.txt
是文件名)

这是错误的。松开
文件
周围的方括号。您传递的是文件名,而不是指向文件名的指针

mov ebx, file ; const char *filename
mov eax, 5  
mov ecx, 0  
int 80h     

我在这里看到很多错误,顺序如下:

mov ebx, [file] ; name of the file  
mov eax, 5  
mov ecx, 0  
int 80h
这里,如前所述,u必须丢失方括号(因为函数需要指针,而不是值)

在这里,您必须先从eax保存文件描述符,然后再写入值3,否则您将丢失它

mov eax, 4  
mov ebx, 1
mov ecx, buffer 
mov edx, len    
int 80h
嗯。这里我们使用ebx寄存器,所以更好的方法是将文件描述符保存在内存中。对于显示,从缓冲区中获取1024字节,这是不正确的。从文件读取后,eax寄存器将包含读取的字符数,因此从文件读取后,最好将eax寄存器中的值存储在edx中

mov eax, 6  
int 80h
再说一遍。U关闭文件,但ebx包含污垢,尽管它必须包含文件描述符

正确的代码必须如下所示:

section .data
  file db "text.txt",0 ;filename ends with '\0' byte
section .bss
  descriptor resb 4 ;memory for storing descriptor
  buffer resb 1024
  len equ 1024
section .start
global _start
_start:
  mov eax,5 ;open
  mov ebx,file ;filename
  mov ecx,0 ;read only
  int 80h ;open filename for read only

  mov [descriptor],eax ;storing the descriptor

  mov eax,3 ;read from file
  mov ebx,[descriptor] ;your file descriptor
  mov ecx,buffer ;read to buffer
  mov edx,len ;read len bytes
  int 80h ;read len bytes to buffer from file

  mov edx,eax ;storing count of readed bytes to edx
  mov eax,4 ;write to file
  mov ebx,1 ;terminal
  mov ecx,buffer ;from buffer
  int 80h ;write to terminal all readed bytes from buffer

  mov eax,6 ;close file
  mov ebx,[descriptor] ;your file descriptor
  int 80h ;close your file

  mov eax,1
  mov ebx,0
  int 80h

这不是一个完美的代码,但它应该可以工作

哇,这段代码碰巧可以工作真是太好笑了,因为
\uu NR\u read
=3=stdin、stdout和stderr之后的第一个免费fd编号。因此,成功的
open()
将返回3,除非您使用
/a.out 3运行程序。您可以
推送描述符,或者更好地将其复制到
esi
或其他地方。对于临时整数,不需要静态存储。或者更好,
mov-ebx,eax
/
mov-eax,3
。您不必按任何顺序分配寄存器,只要在
int 0x80
时寄存器具有正确的值即可。另外,您可以在
write()
之前执行
close()
,这样您仍然可以在
ebx
中使用fd。很好的一点是,您应该
write()
使用与从
read()
中获得的len匹配的len,但您忘记在您的版本中修复它:P您仍然有OP的愚蠢
movedx,len
。U关闭文件,但实际上,ebx中含有污垢,
ebx=1
,所以它关闭了标准输出。Linux的
int0x80
ABI保留所有寄存器(当然除了eax),因此ebx仍然具有
movebx,1
中的值。(见附件)。
mov eax, 4  
mov ebx, 1
mov ecx, buffer 
mov edx, len    
int 80h
mov eax, 6  
int 80h
section .data
  file db "text.txt",0 ;filename ends with '\0' byte
section .bss
  descriptor resb 4 ;memory for storing descriptor
  buffer resb 1024
  len equ 1024
section .start
global _start
_start:
  mov eax,5 ;open
  mov ebx,file ;filename
  mov ecx,0 ;read only
  int 80h ;open filename for read only

  mov [descriptor],eax ;storing the descriptor

  mov eax,3 ;read from file
  mov ebx,[descriptor] ;your file descriptor
  mov ecx,buffer ;read to buffer
  mov edx,len ;read len bytes
  int 80h ;read len bytes to buffer from file

  mov edx,eax ;storing count of readed bytes to edx
  mov eax,4 ;write to file
  mov ebx,1 ;terminal
  mov ecx,buffer ;from buffer
  int 80h ;write to terminal all readed bytes from buffer

  mov eax,6 ;close file
  mov ebx,[descriptor] ;your file descriptor
  int 80h ;close your file

  mov eax,1
  mov ebx,0
  int 80h