我想要补充一些内容。计算机上的程序通常分为三个部分,但也有其他部分。
代码段 - .code,.text:
http://en.wikipedia.org/wiki/Code_segment
在计算机中,代码段,也称为文本段或简称文本,是一个词语,用于指代包含可执行指令的内存或对象文件的一部分。它具有固定的大小,并且通常是只读的。如果文本部分不是只读的,则特定的架构允许自修改代码。如果只读代码可以被同时执行的多个进程执行,则它是可重入的。作为一个内存区域,代码段驻留在内存的较低部分或其底部,以防止堆栈溢出覆盖它。
数据段 - .data:
http://en.wikipedia.org/wiki/Data_segment
数据段是程序中的一个部分,它位于对象文件或内存中,并包含由程序员初始化的全局变量和静态变量。它具有固定的大小,因为在程序加载之前,该部分中的所有数据都由程序员设置。但是,它不是只读的,因为变量的值可以在运行时更改。这与Rodata(常量,只读数据)部分以及代码段(也称为文本段)形成对比。
BSS:
http://en.wikipedia.org/wiki/.bss
在计算机编程中,.bss或bss(最初代表由符号开始的块)被许多编译器和链接器用作包含仅填充零值数据的静态变量和全局变量的一部分的名称(即当执行开始时)。它通常被称为“bss节”或“bss段”。程序装载器在加载程序时初始化分配给bss部分的内存。
寄存器是CPU存储数据或内存地址的设施,如其他人所述。对寄存器执行操作,例如
add eax, ebx
,根据汇编语言方言的不同,这意味着不同的事情。在这种情况下,这意味着将ebx的内容添加到eax中并将其存储在eax中(NASM语法)。在GNU AS(AT&T)中等价于:
movl $ebx, $eax
。不同的汇编语言方言有不同的规则和运算符。出于这个原因,我不喜欢MASM - 它与NASM、YASM和GNU AS非常不同。
与C没有普遍互动。ABI指定了如何实现;例如,在x86(unix)上,您会发现一个方法的参数被推送到堆栈上,而在x86-64上的Unix上,前几个参数将被放置在寄存器中。两种ABI都期望函数的结果存储在eax/rax寄存器中。
这是一个32位加法例程,可以在Windows和Linux上汇编。
_Add
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov ecx, [ebp+12]
add eax, ecx
pop ebp
ret
在这里,您可以看到我的意思。 "返回"值在eax中找到。相比之下,x64版本将如下所示:
_Add
push rbp
mov rbp, rsp
mov eax, edi
mov ecx, esi
add eax, ecx
pop rbp
ret
有一些文件可以定义这种东西。这里是UNIX x64 ABI的链接:http://www.x86-64.org/documentation/abi-0.99.pdf。我相信你可能会找到任何处理器、平台等所需的ABIs。
如何在汇编语言中操作数组?使用指针算术。如果整数大小为4个字节,则在基地址eax处下一个存储的整数将位于[eax+4]
。您可以通过调用malloc/calloc来创建此空间,或者调用内存分配系统调用(在您的系统上),以实现这一点。
什么是“堆”?根据维基百科,它是保留用于动态内存分配的内存区域。在您调用calloc、malloc或内存分配系统调用之前,您在汇编程序中看不到它,但它确实存在。
对于篇幅,很抱歉。