【问题标题】:unable to read from file when user provides filename (x86 assembly program using nasm)当用户提供文件名时无法从文件中读取(使用 nasm 的 x86 汇编程序)
【发布时间】:2013-11-29 17:50:56
【问题描述】:

我在尝试打开文件并从中读取时遇到问题。系统会提示用户输入文件名。

程序编译没有错误,但不显示任何内容。当我在.data 部分对文件名进行硬编码时,它运行良好,但是当我从用户那里获取文件名时,它无法读取文件。我在哪里做错了?我找不到任何错误。

使用硬编码名称输出:welcome

用户输入姓名时输出:���

这是我的代码:

节 .data promptUsr db '输入文件名:',0xA,0xD lenPrompt equ $-promptUsr 信息数据库 1 ;file_name db 'data.txt' (注意:使用硬编码名称时有效) .bss 节 fd_in resb 1 缓冲资源 7 文件名 resb 20 部分 .text 全局_start _开始: ;提示用户输入文件名 mov eax,4 ;sys_write mov ebx,1 ;标准输出 mov ecx,promptUsr mov edx,lenPrompt 整数 0x80 ;读取文件名(注意:当用户输入相同的名称'data.txt'时,这是输出:���) 移动 eax,3 mov ebx,2 mov ecx,file_name ;(注意:尝试使用 'dword[file_name]',不起作用) 移动 edx,20 整数 0x80 ;打开文件 移动 eax,5 mov ebx,file_name ;(注意:也尝试使用 'dword[file_name]',也不起作用) mov ecx,2 ;读 n 写 mov edx,7777h ;所有文件权限 整数 0x80 mov [fd_in],eax ;读取文件的 7 个字节 移动 eax,3 mov ebx,[fd_in] mov ecx,缓冲区 移动 edx,7 整数 0x80 ;关闭文件 移动 eax,6 整数 0x80 ;打印出读过的内容 移动 eax,4 移动 ebx,1 mov ecx,缓冲区 移动 edx,7 整数 0x80 ;结束程序 移动 eax,1 整数 0x80

【问题讨论】:

  • 也很想知道如何在打开文件之前先检查文件是否存在。谢谢任何人

标签: linux file assembly x86 nasm


【解决方案1】:

添加到迈克尔所说的... 1) fd_in 太小 - 使它成为 resd 1。 2) sys_read 不返回以零结尾的字符串,而sys_open 想要一个。

mov byte [ecx + eax - 1], 0

在文件名的sys_read 之后应该以零结尾。

【讨论】:

  • thanx frank.just 试过了,但无法正确读取我应该在哪里插入 mov 字节 [ecx + eax - 1], 0 c0de?在 'mov ebx,0' 之后插入它不起作用。在 mov ecx,file_name 之后插入也不起作用......代码运行但没有任何显示。注意当我将 resd 1 更改为 resb1 时会输出以下奇怪的符号,这是输出:��当我将其设为 resb 2 时,输出是:�� resb 3 输出是:�将其返回到 resd 1,没有显示。这里有什么问题?那么当我硬编码文件名但我只为文件描述符保留一个字节时,为什么程序运行良好?
  • 将零终止行放在int 80h 之后。 ecx (仍然)是您的缓冲区,eax 是读取的长度,包括终止换行符。你是对的,那里有一个隐藏的角色。我们想用另一个隐藏字符覆盖它——sys_open 期望出现的零。
  • 天哪!!终于!非常感谢..它现在按预期工作。你是救世主。这段代码从早上起就让我头疼。有趣的是如何在 int 80h 之后添加终止 0。我认为在 int 80h 之后文件名已经保存。现在剩下的就是检查文件是否存在,如果不存在则显示消息并退出程序。我是组装 n 的新手,不知道 syscall 33 或 18 r 是如何使用的。在 mov [fd_in],eax 之前使用 cmp eax,0 jbe end 怎么样?
  • 试试man 2 access - 它是用 C 语言编写的,但你可以弄清楚。或者您可以按照您的建议在sys_open 之后检查eax 中的值,如果没有成功,请查看为什么不成功。 (errno.h)
【解决方案2】:

看起来您正在尝试从STDERR 读取:

mov eax,3   
mov ebx,2   
mov ecx,file_name   ;(NOTE:tried using 'dword[file_name]',doesnt work)
mov edx,20

如果您想从STDIN 读取,那mov ebx,2 应该是mov ebx,0


也很想知道如何在打开文件之前先检查文件是否存在

如果您使用 sys_open 而不设置 O_CREAT 标志,如果文件不存在,它应该会失败并返回 -1。如果您愿意,也可以使用access (syscall 33) 或stat (syscall 18)。

【讨论】:

  • thanx michael 快速回复....我已将 mov ebx,2 更改为 mov ebx,0 但仍然无法读取文件..只有当我声明文件时才能读取文件代码中的名称。我认为可能使用 std_in 会在文件名的末尾插入一些隐藏字符(终止字符)或其他内容?也许在使用该名称打开文件之前应该去掉这个不可见的字符?所以如果是这种情况,你知道如何从字符串中删除最后一个字符吗?当我添加代码以打印出用户输入的内容时,它会很好地显示它,即“data.txt”有什么想法吗?
猜你喜欢
  • 2017-08-12
  • 2013-04-15
  • 2013-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
  • 2012-05-08
相关资源
最近更新 更多