2014-10-17 55 views
-1

我是Linux的新手,用于汇编程序设计(GAS)和英语。所以,如果我写错了,抱歉。我希望谷歌翻译能够帮到我,写得不错。当我编写系统调用时,Linux会做什么?

我想知道如何将一组数字(存储在.data中)写入文本文件中,而无需调用任何库中的函数(如printf()),并且只通过汇编程序进行操作。我不想要现成的解决方案。我想知道我的写入调用后Linux内核的功能。怎么运行的?它是如何设计的?

我试图将数字列表打印到STDOUT中,但我在终端中收到奇数号。我认为这是因为我不明白如何正确使用写入系统调用。

这是我得到了现在

.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",而不是号码列表。

+0

这是一个令人难以置信的广泛的主题,需要相当多的背景知识来了解我怀疑你没有的东西。你可能想把它分解成一些大小的块,向我们展示你迄今为止付出的努力以及你被困在哪里。 – tangrs 2014-10-17 10:52:01

+0

阅读http://www.tldp.org/HOWTO/Assembly-HOWTO/它是相关的 – 2014-10-20 13:19:15

+0

我读了Jonathan Bartlett的“从头开始编程”。哪个更好? – user2422443 2014-10-20 13:31:51

回答

4

首先:

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

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

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

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

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

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

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

---编辑---

关于您编辑的问题:

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

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

+0

哇!这很复杂。谢谢!我编辑了我的问题,并使其更具体。你可以看看它,并让我思考方向吗?我必须理解正确地做到这一点? – user2422443 2014-10-20 13:21:16

+0

知道了!这就是我需要的!非常感谢你! – user2422443 2014-10-20 17:48:17

相关问题