【问题标题】:Need guidance on understanding basic assembly需要了解基本装配的指导
【发布时间】:2013-06-09 02:33:09
【问题描述】:

我一直在尝试掌握如何在汇编中进行一些简单的编程。我正在查看一个教程 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 等于dollarsign 减去msg 变量?美元符号是什么?某种运算符?还有文本部分中的说明,显然是 mov ebx,1,或者似乎告诉程序使用 STDOUT?将 1 移到 ebx 寄存器是设置标准输出的标准指令吗?

也许有人可以推荐一些更全面的教程?我想弄脏组装,如果你愿意的话,我需要自学一些……“核心基础”。感谢大家的帮助!

【问题讨论】:

  • 出于好奇,是什么促使您想学习汇编?我不是批评你想要,只是想知道为什么。使用过高级语言后,我个人认为没有必要学习汇编。我错过了什么吗?
  • 数据部分没有粘贴到文本部分,代码可以简单地以任何它认为合适的方式使用数据。 db 表示会有原始字节,表示字符串“Hello, world!”的字节。后跟换行符(0xa,十六进制表示 10,是 ascii 中的换行符)。 len equ $ - msg的意思是“声明len等于这里减去msg”,“这里减去msg”当然是中间的字节数,即字符串的长度。 mov ebx, 1 只是将 ebx 设置为 1,但值 1 表示用作文件句柄时的 STDOUT。
  • @wagregg,你曾经从事过任何类型的裸机开发吗?
  • 不,我一直站在巨人的肩膀上。编写简单的代码行,在幕后移动大山。对于所有低级的东西,我可能不够聪明。
  • @wagregg 我在工作中涉足安全领域,没什么可紧张的。有一次我阅读并查看了一个挑战项目,其中一部分是查看与恶意代码有关的 asm 文件,我相信是 shell 代码吗?已经有一段时间了......我只是无法完全理解它。从那时起,我一直想熟悉组装。拓宽我的个人技能,然后希望在工作中扩大我的视野;)

标签: linux assembly x86 nasm


【解决方案1】:

[NB - 我不知道你使用的是什么汇编语言,所以我只是对这些东西的某些部分进行了一些“最佳猜测”。如果有人可以帮助澄清,那就太好了。]

看起来程序的“框架”在文本部分,“肉”在数据部分......?

文本部分包含构成程序的可执行指令。数据部分包含所述程序将要操作的数据。之所以有两个不同的部分,是为了让程序加载器和操作系统能够为您提供一些保护。例如,文本部分可以加载到只读内存中,数据部分可以加载到标记为“不可执行”的内存中,因此代码不会意外(或恶意)从该区域执行。

我假设程序在编译时执行文本部分,并将数据部分中的数据填充到文本部分?

程序(文本部分中的指令)通常会引用符号并操作数据部分中的数据,如果这是您所要求的。

bss/text/data 部分的交互对我来说有点陌生。

BSS 部分与数据部分类似,不同之处在于它都是零初始化的。这意味着它实际上不需要占用可执行文件中的空间。程序加载器只需在内存中创建一个大小合适的零字节块。您的程序没有 BSS 部分。

还在数据部分的 msg 和 len.... 变量中?提到了,它们后面跟着一些我不知道该怎么做的信息。 msg后面跟着db,这是什么意思?

msglen 是某种变量,是的。 msg 是一个全局变量,指向后面的字符串——db 表示data byte,表示汇编器应该只发出后面的文字字节。 len 被设置为字符串的长度(更多内容见下文)。

然后是文字,然后是0xa,0xa是干什么用的?

0x0a 是 ASCII 换行符的十六进制值。

len 后面也跟着 equ,这是否意味着等于?

是的。

len 等于 $ 符号减去 msg 变量?什么是美元符号?某种运算符?

$ 表示“当前位置”。当汇编器开始工作时,它会跟踪在计数器中生成了多少字节的数据和代码。所以这段代码是说:“从当前位置减去msg标签的位置并将该数字存储为len”。由于“当前位置”刚刚超过字符串的末尾,因此您可以在此处获得长度。

还有文本部分中的说明,显然是 mov ebx,1,或者似乎告诉程序使用 STDOUT?将 1 移到 ebx 寄存器是设置 stdout 的标准指令吗?

程序正在通过int 0x80 指令进行系统调用。在此之前,它必须以操作系统期望的方式进行设置——在这种情况下,看起来就像在ebx1 中放置一个1 来表示stdout,以及其他三个寄存器——@987654338 中的消息长度@,指向ecx 中消息的指针,以及eax 中的系统调用号。我猜你是在 linux 上——你可以从 google 查找系统调用表而不用太麻烦,我敢肯定。

也许有人可以推荐一些更全面的教程?

对不起,不是我的头。

【讨论】:

  • 这对我来说是一些很棒的信息,所以我可以在脑海中拼凑起来。采取婴儿步骤。当我努力完全理解所提供的示例代码中的每一行时,我一定会查看您的答案。然后它会导致代码更令人头疼。非常感谢卡尔!
  • 没问题,如果有什么我可以充实的内容来帮助您理解,请告诉我。
  • 可能感兴趣的教程:drpaulcarter.com/pcasm - 对您来说可能不够“低级”,但适用于多个操作系统。 asm.sourceforge.net 的其他人(面向 Linux) - (这可能是你所拥有的)。如果您没有运行 Linux,那么您的示例代码将无法运行……但对学习仍然有用……
  • 顺便说一句,这是 x86 Linux 上的 NASM 语法。我可以说是因为其他风格的英特尔语法会使用mov ecx, OFFSET msg。一些链接请参见stackoverflow.com/tags/intel-syntax/info
  • 是的,这是 NASM,db 是 NASM 中的定义字节,相当于在高级编程语言中分配变量。 equ 等同于它等同于 C 中的“#define”。部分根据内存段进行分类。用于存储源代码的文本段。用于存储str msg = 'Hello'等初始化变量的数据段。 BSS段,用于存储static int len等初始化变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 2014-12-19
  • 2013-03-28
相关资源
最近更新 更多