我已经涉足到了解如何在汇编中进行一些简单的编程。我正在阅读一个教程hello world程序,他们解释的大部分内容都很有意义,但是他们真的很喜欢它。我想帮助理解程序的某些不同部分。这是他们的教程示例 -
section .text
global main ;must be declared for linker (ld)
main: ;tells linker entry point
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db 'Hello, world!', 0xa ;our dear string
len equ $ - msg ;length of our dear string
有文本部分和数据部分。数据部分似乎保存了我们用户定义的程序信息。看起来程序的“框架”在文本部分,而“肉”在数据部分......?我假设程序在编译时执行文本部分,数据部分的数据填入文本部分? bss / text / data部分的交互对我来说很陌生。另外在msg和len ....变量的数据部分?提到,他们后面跟着一些信息,我不知道该怎么做。 msg之后是db,这是什么意思?然后是文本,然后是0xa,什么是0xa? len之后是equ,这意味着是否等于? len等于dollarign减去msg变量?什么是美元符号?一种运营商?文本部分中的说明,mov ebx,1显然,或似乎告诉程序使用STDOUT?将1移动到ebx寄存器是设置stdout的标准指令吗?
也许某人有更全面的教程推荐?我希望通过装配变脏,并且需要自学一些......“核心基础”,如果你愿意的话。谢谢你的帮助!
答案 0 :(得分:11)
[NB - 我不知道你正在使用什么汇编语言,所以我只是对这些东西的某些部分做了一些“最好的猜测”。如果有人可以帮助澄清,那就太棒了。]
看起来程序的“框架”在文本部分,“肉”在数据部分......?
文本部分包含组成程序的可执行指令。数据部分包含所述程序将要运行的数据。有两个不同部分的原因是允许程序加载器和操作系统能够为您提供一些保护。例如,文本部分可以加载到只读存储器中,并且数据部分可以加载到标记为“不可执行”的存储器中,因此不会从该区域意外(或恶意)执行代码。
我假设程序在编译时执行文本部分,数据部分的数据填入文本部分?
程序(文本部分中的说明)通常引用符号并操纵数据部分中的数据,如果这就是您所要求的。
bss / text / data部分的互动对我来说很陌生。
BSS部分类似于数据部分,但它全部为零初始化。这意味着它不需要实际占用可执行文件中的空间。程序加载器只需在内存中制作一个适当大小的零字节块。您的程序没有BSS部分。
另外在msg和len ....变量的数据部分?提到,他们后面跟着一些信息,我不知道该怎么做。 msg之后是db,这是什么意思?
msg
和len
是一种变量,是的。 msg
是一个全局变量,指向后面的字符串 - db
表示data byte
,表示汇编程序应该只发出后面的字面字节。 len
被设置为字符串的长度(更多在下面)。
然后是文本,然后是0xa,什么是0xa?
0x0a
是ASCII换行符的十六进制值。
len之后是equ,这意味着是否等于?
是
len等于dollarign减去msg变量?什么是美元符号?一种运营商?
$
表示“当前位置”。当汇编程序开始工作时,它会跟踪计数器中生成的数据字节数和代码数。因此,此代码说:“从当前位置减去msg
标签的位置,并将该数字存储为len
”。由于“当前位置”刚刚超过字符串的末尾,因此您可以获得长度。
文本部分中的说明,mov ebx,1显然,或似乎告诉程序使用STDOUT?将1移动到ebx寄存器是设置stdout的标准指令吗?
程序正在通过int 0x80
指令进行系统调用。在此之前,它必须以操作系统期望的方式进行设置 - 在这种情况下,似乎将1
放在ebx1
中表示stdout
,以及其他三个寄存器 - edx
中的消息长度,ecx
中消息的指针以及eax
中的系统调用号。我猜你是在Linux上 - 你可以从谷歌查找系统调用表而不会有太多麻烦,我敢肯定。
也许某人有更全面的教程推荐?
对不起,不是我的头脑。