【问题标题】:What Linux does when I make write system call? [closed]当我进行写系统调用时Linux会做什么? [关闭]
【发布时间】:2014-10-17 10:37:58
【问题描述】:

我是 Linux、汇编编程 (GAS) 和英语的新手。所以,对不起,如果我写错了。我希望谷歌翻译能帮助我把它写得还不错。

我想知道如何在不调用任何库(如printf())的函数的情况下将存储在.data 部分中的一组数字写入文本文件,并通过仅汇编程序来执行此操作。我不想要现成的解决方案。我想知道在我的 write 调用之后 Linux 内核做了什么。这个怎么运作?它是如何设计的?

我正在尝试将数字列表打印到 STDOUT,但我在终端中收到一个奇怪的符号。我认为这是因为我不明白如何正确使用 write 系统调用。

这就是我现在得到的

.section .data    
list:                               .long   12, 31, 42

.section .text    
.globl _start  
_start:   
movl $4, %eax  
movl $1, %ebx  
movl $list, %ecx  
movl $12, %edx  
int  $0x80  
movl $1, %eax  
movl $0, %ebx  
int  $0x80

此代码适用于.ascii "Hello world\0",但不适用于数字列表。

【问题讨论】:

  • 这是一个非常广泛的主题,需要相当多的背景知识才能理解,我怀疑你没有。你可能想把它分解成一口大小的块,向我们展示你到目前为止所做的努力以及你遇到的困难。
  • 我读过 Jonathan Bartlett 的“从头开始编程”。哪个更好?

标签: assembly linux-kernel system-calls gnu-assembler


【解决方案1】:

首先:

甚至库函数(例如来自 libc.so)在内部也使用系统调用。

系统调用或多或少是 CALL 指令的一种特殊变体。该指令将调用一些代码(如 CALL 所做的那样),但它会将 CPU 置于特权模式(在此模式下 CPU 可以访问在用户模式下无法访问的地址)以及要调用函数的地址位置是固定的(由只能在特权模式下访问的特殊寄存器定义)。

被调用的函数评估 EAX 寄存器(假设 x86 为 32 位 Linux)并执行所需的操作(如果 EAX 为 4,则完成“写入”)。

系统调用之外的代码非常非常庞大和复杂。最后,系统调用会导致将数据写入 I/O 端口和内存区域,例如属于磁盘驱动器或显卡的内存区域。

例如,为了将字符写入屏幕,数据被写入位于未映射地址 0xB8000 的图形内存中,该地址对应于旧内核中的映射地址 0xC00B8000。

这意味着当屏幕处于文本模式时,向这样的地址写入一些数据的“mov”指令将导致屏幕上显示一个字符。

但是这个地址 (0xC00B8000) 只能在 CPU 处于特权模式时访问。否则抛出异常(这也是某种由硬件而非软件引起的“CALL”);在这种情况下调用的例程会打印出类似“总线错误”的内容并停止程序。

--- 编辑---

关于您编辑的问题:

“write”系统调用会将 ASCII 字符写入屏幕或文件。

如果你想写数字,你必须将数字转换为 ASCII 字符序列。

【讨论】:

  • 哇!情况很复杂。谢谢!我编辑了我的问题并使其更具体。你能看看它并告诉我思考的方向吗?我必须明白什么才能正确地做到这一点?
  • 知道了!这就是我需要的!非常感谢!
猜你喜欢
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 2013-08-04
  • 2013-05-10
相关资源
最近更新 更多