我是Linux的新手,装配编程(GAS)和英语。所以,抱歉,如果我写错了。我希望谷歌翻译能够帮助我写下这一切并不是太糟糕。
我想知道如何将一组存储在.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 :(得分:4)
首先:
甚至库函数(例如来自libc.so)也在内部使用系统调用。
系统调用或多或少是CALL指令的特殊变体。该指令将调用一些代码(如CALL所做),但它会将CPU置于特权模式(在此模式下,CPU可以访问在用户模式下无法访问的地址)以及要调用的函数的地址位于固定的位置(由特殊寄存器定义,只能在特权模式下访问)。
调用的函数评估EAX寄存器(假设32位Linux用于x86)并执行所需的操作(如果EAX为4,那么"写"完成)。
系统调用之外的代码非常非常庞大且复杂。最后,系统调用将导致将数据写入I / O端口和内存区域,例如属于磁盘驱动器或图形卡。
要将字符写入屏幕,例如将数据写入图形存储器,该图形存储器位于未映射的地址0xB8000,对应于较旧内核中的映射地址0xC00B8000。
这意味着" mov"将一些数据写入此类地址的指令将导致屏幕处于文本模式时屏幕上显示一个字符。
但是,只有CPU处于特权模式时才能访问此地址(0xC00B8000)。否则会抛出异常(这也是某种" CALL"这是由硬件引起的,而不是由软件引起的);在这种情况下调用的例程会打印出类似"总线错误"并停止该计划。
---编辑---
关于您编辑过的问题:
"写"系统调用会将ASCII字符写入屏幕或文件。
如果你想写数字,你必须将数字转换为ASCII字符序列。