linux x86 汇编语言 sys_read 调用的第一个参数应为 0 (stdin)

2024-05-14

我正在编写一个简单的汇编程序来从标准输入读取(如 scanf)。 这是我的代码。


section .bss
num resb 5

section .txt
global _start

_start:

mov eax,3   ;sys_read
mov ebx,0   ;fd 0
mov ecx,num
mov edx,5
int 0x80

mov eax,4   ;sys_write
mov ebx,1   ;fd 1
mov ecx,num
mov edx,5
int 0x80

mov eax,1   ;sys_exit
mov ebx,0   ;return 0
int 0x80

现在可以正常工作,可以读取和打印。

因此,我尝试将 sys_read 调用中的文件描述符值更改为 1(stdout)、2(syserr)。

Code.


section .bss
num resb 5

section .txt
global _start

_start:

mov eax,3   ;sys_read
mov ebx,1   ;fd 1
mov ecx,num
mov edx,5
int 0x80

mov eax,4   ;sys_write
mov ebx,1   ;fd 1
mov ecx,num
mov edx,5
int 0x80

mov eax,1   ;sys_exit
mov ebx,0   ;return 0
int 0x80

这段代码也可以正常工作。
我的问题是,即使将文件描述符从 0 更改为 1,为什么这段代码仍能正常工作。 sys_read 应该取 0 作为 fd。


当您测试它时,您正在使用连接到终端的 stdin、stdout 和 stderr 来运行程序。碰巧该文件描述所有 3 个文件描述符都是读/写。

fd 0 并没有什么神奇之处可以阻止文件描述符的读/写。

我认为 shell 可以分别打开只读和只写终端,而不是运行所有 3 个标准文件描述符都是同一读写文件描述的重复项的程序。 (设置为dup2 http://man7.org/linux/man-pages/man2/dup.2.html)。但这不是 bash(或启动 bash 的终端仿真器)的设计方式。


尝试运行你的sys_read(1, ...)stdin 是一个管道或文件,绝对只为读取而打开,而 stdout 是一个只为写入而打开的 fd 版本。

$ echo foo | strace ./read1 > foo.out
execve("./read1", ["./read1"], 0x7fff68953560 /* 52 vars */) = 0
strace: [ Process PID=31555 runs in 32 bit mode. ]
read(1, 0x80490ac, 5)                   = -1 EBADF (Bad file descriptor)
write(1, "\0\0\0\0\0", 5)               = 5
exit(0)                                 = ?
+++ exited with 0 +++

So read(1, num, 5)-EBADF(错误的文件描述符),因为 fd 1 是只写 fd,在该进程的 fork/execve 之前由 shell 打开。write(1, ...)仍然发生,因为你的程序没有做任何错误检查。 (那很好;我们有类似的工具strace所以我们在尝试系统调用时可以偷懒)。


但请注意重定向 stdin 没有任何区别;你的程序从不使用fd 0!

当 fd 1 连接到 tty 时,无论输入重定向如何,从中读取都会从终端读取。

$ echo test | strace ./read1
execve("./read1", ["./read1"], 0x7ffc3c42d620 /* 52 vars */) = 0
strace: [ Process PID=31462 runs in 32 bit mode. ]
read(1,                                   # it blocked here until I pressed return
"\n", 5)                        = 1
write(1, "\n\0\0\0\0", 5
)               = 5
exit(0)                                 = ?
+++ exited with 0 +++

在另一个终端中read1被暂停等待read()回来:

$ ll /proc/$(pidof read1)/fd 
total 0
lr-x------ 1 peter peter 64 Feb 22 18:17 0 -> pipe:[13443590]
lrwx------ 1 peter peter 64 Feb 22 18:17 1 -> /dev/pts/17
lrwx------ 1 peter peter 64 Feb 22 18:17 2 -> /dev/pts/17
lrwx------ 1 peter peter 64 Feb 22 18:17 49 -> socket:[405352]
lrwx------ 1 peter peter 64 Feb 22 18:17 53 -> socket:[405353]

请注意 fd 1 上的 RWX:该符号链接的权限反映了它是读、写还是读+写 fd。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux x86 汇编语言 sys_read 调用的第一个参数应为 0 (stdin) 的相关文章

随机推荐

  • 以编程方式检测应用程序是否正在设备或模拟器上运行

    我想知道我的应用程序在运行时是在设备还是模拟器上运行 有没有办法检测到这一点 原因是用模拟器测试蓝牙 api http volcore limbicsoft com 2009 09 iphone os 31 gamekit pt 1 woo
  • 绝对导入不起作用,但相对导入起作用

    这是我的应用程序结构 foodo setup py foodo init py foodo py models py foodo foodo foodo py从导入类models py module from foodo models im
  • 如何使用 Google 的 GithubBrowserSample 方法在片段之间共享视图模型?

    我对 Android 架构组件的使用非常陌生 因此我决定使用 GithubBrowserSample 来构建我的应用程序来实现我的许多用例 但我有一个问题 我不知道使用这种方法在片段之间共享视图模型的正确方法是什么 我想共享视图模型 因为我
  • 实体框架:无效的列名称 *_ID 1

    我正在尝试为几个名为 的表实现 DbContextEmployee and Department 员工和部门之间的关系是多对一的 即部门可以有很多员工 下面是我设计的EntityFramework类 CodeFirst方法 Table Em
  • 更改语言 Flutter 的按钮

    我正在 Flutter 中构建一个应用程序 到目前为止 我正在使用 JSON 国际化 其中应用程序的语言基于用户手机中默认的语言 它工作得很好 但我想给用户有机会在不更改手机系统语言设置的情况下更改语言 只需单击按钮 然后应用程序即可更改语
  • java.lang.IllegalAccessError:预验证类中的类引用在运行测试项目时解析为意外实现?

    在实施项目工作正常之后 我使用第三方库 zxing 实施了项目 然后在我编写了一个测试项目对我的项目进行单元测试之后 运行测试项目后 主项目 类及其方法没有给出任何信息错误 但如果在主项目的该方法中使用任何 zxing 框架类 则会在运行时
  • 使用 .htaccess 重定向到动态相对路径?

    是否可以使 htaccess 理解 动态相对路径并正确重定向到它们 我的设置如下 http domain com htroot aaa xyz http domain com htroot bbb xyz http domain com h
  • 计算字符串中的唯一单词

    下面我尝试将字符串数组提供给一个函数 该函数将唯一单词添加到单词数组中 并且如果该单词已经在数组中 则增加计数数组中相应元素的计数 var words var counts calculate a b calculate a c funct
  • Django 查询:“datetime + delta”作为表达式

    好吧 我的问题如下 假设我有下一个模型 这是一个简单的情况 class Period models Model name CharField field specs here start date DateTimeField field s
  • 哪种反应钩子与 firestore onsnapshot 一起使用?

    我在我的 React Native 应用程序中使用了大量的 Firestore 快照 我也在使用 React hooks 代码看起来像这样 useEffect gt someFirestoreAPICall onSnapshot snaps
  • Spring(MVC)SQL注入避免?

    我想知道 Spring MVC 如何处理 SQL 注入 以及其他安全问题 XSS 代码 javascript 注入等 我主要讨论的是转义添加到数据库等的值 我似乎找不到任何答案 因为每次我搜索涉及依赖注入的 spring sql 注入结果时
  • Grunt-browserify+mapify+coffeescript = 未通过相对路径找到模块

    我尝试让 grunt browserify 使用 Coffeescript 的相对路径 但当我尝试构建源代码时总是收到错误消息 gt gt Error module src app utils includeMixin not found
  • 如何使用 python、openCV 计算图像中的行数

    我想数纸张 所以我正在考虑使用线条检测 我尝试过一些方法 例如Canny HoughLines and FLD 但我只得到处理过的照片 我不知道如何计算 有一些小线段就是我们想要的线 我用过len lines or len contours
  • 规范化 solaris 上的路径名

    在 GNU 系统上我只会使用readlink f SOME PATH 但 Solaris 没有 readlink 我更喜欢在 bash 中运行良好的程序 但如果需要的话其他程序也可以 Edit 到目前为止 我想到的最好的方法是使用 cd 和
  • 如何将数据从一个视图传递到下一个视图?

    我正在制作一个下载排队系统来下载视频 处理下载的排队代码位于另一个视图控制器中 现在我的问题是如何将下载的 URL 传递到另一个视图而不推送到另一个视图控制器 如下所示 ViewConntroller View ViewConntrolle
  • 如何将UTC时间转换为unix时间戳

    我正在寻找将 UTC 时间字符串转换为 unix 时间戳的选项 我的字符串变量是02 28 2016 10 03 46 PM并且需要将其转换为 unix 时间戳 例如1456693426 知道该怎么做吗 首先 unix时间戳14566934
  • Google Chrome 上的 xsl:include 和 xsl:param,带有 jQ​​uery 转换插件

    我一直尝试在 Google Chrome 中使用 XSL 但没有成功 我读到 Chrome 在 XSLT 方面存在一些错误 其中之一是它不支持 xsl include 可以在这里检查错误 http code google com p chr
  • Web API 的 ASP.NET MVC Core 控制器 PATCH 方法

    给定一个数据库表 Person 包含 3 列 Id 名字和姓氏 使用真实的 DbContext 时 ASP NET Core Web API MVC 控制器方法 PATCH 仅修改姓氏 看起来如何 我根本不知道如何实现它 并且找不到相关教程
  • 自定义列表字段点击事件

    我正在编写一个应用程序 其中我创建了用于显示列表视图的自定义列表字段 我的 CustomListField 包含连续的一个图像和文本 我正在通过单击列表字段行获取字段更改侦听器 但我也想将字段更改侦听器放在图像上 谁能告诉我我该怎么做 这是
  • linux x86 汇编语言 sys_read 调用的第一个参数应为 0 (stdin)

    我正在编写一个简单的汇编程序来从标准输入读取 如 scanf 这是我的代码 section bss num resb 5 section txt global start start mov eax 3 sys read mov ebx 0