汇编语言学习(2)
2023-12-17 20:04:24
更好的阅读体验,请点击 YinKai’s Blog。
基本语法
汇编程序可以分为三个部分:
- 数据部分(data section)
- 未初始化数据部分(bss section)
- 文本部分(text section)
data 部分
? 数据部分通常用于存储程序中需要初始化的数据。这可以包括常量、变量和其他静态数据。这个部分的数据在程序运行之前被初始化,并且在整个程序的执行过程中保持不变。
? 声明数据部分的语法如下:
section .data
bss 部分
? 未初始化数据部分用于存储程序中未初始化的全局和静态变量。与数据部分不同,bss 部分的变量在程序加载时不会被初始化,而是在运行时由系统初始化为零或空值。这样可以节省可执行文件的大小,因为在文件中只需要记录这些变量的名称和大小,而不需要存储它们的实际值。
? 声明 bss 部分的语法如下:
section .bss
text 部分
? 文本部分包含程序的实际代码。这是程序的主要执行部分,包括机器指令和指令的地址。在这个部分,汇编程序将源代码翻译成机器可执行的指令,使得计算机能够按照特定的算法执行相应的操作。
? 声明 文本部分的语法如下:
section .text
注释
? 汇编语言中的注释以分号;
开头。注释可以独立一行存在,也可以与指令在同一行。例如:
; This is a line of comments
add eax, ebx ; adds ebx to eax
汇编语言语句
? 汇编语言程序由三种类型的语句组成:
- 可执行指令:告诉处理器要执行的操作,每条指令包括操作码和操作数
- **汇编器指令或伪操作:**用于影响汇编过程的方面,它们不会生成机器语言指令
- **宏:**一种文本替换机制
汇编语言语句的语法
? 汇编语言语句每行输入一个语句,每个语句都遵循以下格式:
[label] mnemonic [operands] [;comment]
? 方括号中的字段是可选的。
? 基本指令由两部分组成,第一部分是哟啊执行的指令名词(或助记符),第二部分是命令的操作数或参数。
? 以下是一些典型汇编语言语句的示例:
-
MOV指令(数据传送):
MOV AX, 42 ; 将值42存储到寄存器AX中 MOV BX, AX ; 将寄存器AX的值传送到寄存器BX中
-
ADD和SUB指令(加法和减法):
ADD AX, BX ; 将寄存器AX和BX中的值相加,并将结果存储在AX中 SUB CX, 10 ; 从寄存器CX中减去值10,并将结果存储在CX中
-
CMP和JMP指令(比较和跳转):
CMP AX, BX ; 比较寄存器AX和BX的值 JE label ; 如果相等,则跳转到标签label处 JG another_label ; 如果大于,则跳转到另一个标签another_label处 JL target_label ; 如果小于,跳转到目标标签
-
INC和DEC指令(递增和递减):
INC SI ; 将寄存器SI中的值递增1 DEC CX ; 将寄存器CX中的值递减1
-
LOOP指令(循环):
MOV CX, 5 ; 设置循环计数器CX的初始值为5 loop_start: ; 循环开始标签 ; 循环体代码 DEC CX ; 循环计数器递减1 JNZ loop_start; 如果计数器不为零,则跳转到循环开始标签
汇编中的 Hello World 程序
section .data
msg db 'Hello, world!', 0xa ; 要打印的字符串,0xa 是换行符
len equ $ - msg ; 字符串的长度
section .text
global _start ; 必须为链接器(ld)声明的全局入口点
_start: ; 告诉链接器入口点
; write message to stdout
mov eax, 4 ; 系统调用号(sys_write)
mov ebx, 1 ; 文件描述符(标准输出)
mov ecx, msg ; 要写入的消息
mov edx, len ; 消息的长度
int 0x80 ; 调用内核
; exit the program
mov eax, 1 ; 系统调用号(sys_exit)
xor ebx, ebx ; 返回码为0
int 0x80 ; 调用内核
上面的代码被编译并执行后,会输出如下内容:
Hello, world!
在 NASM 中编译和链接汇编程序
? 为了能让上面的程序运行起来,我们需要按下面的步骤编译和链接上述程序:
- 使用文本编译器输入上述代码并将其保存为 hello.asm,后续的操作都在该目录下进行
- 输入
nasm -f elf hello.asm
编译汇编程序-f elf:
这是 NASM 的一个选项,用于指定生成的目标文件的格式。在这里,elf
表示目标文件将采用 ELF(Executable and Linkable Format)格式。- ELF 是一种通用的二进制文件格式,用于可执行文件、目标文件和共享库。
- 如果程序没有问题,就会程序名为 hello.o 的程序目标文件
- 输入
ld -m elf_i386 -s -o hello hello.o
命令,链接目标文件并创建名为 hello 的可执行文件ld
: 这是链接器的命令。链接器的作用是将多个目标文件链接在一起,解析符号引用,生成最终的可执行文件。在执行该命令时,链接器会将系统库和其他必要运行时库链接到目标文件hello.o
中。我们的代码中由于程序只是在标准输出上打印一条消息,因此系统库中的一些 I/O 相关的函数可能被链接进来,以便程序能够正确地执行。-m elf_i386
: 这个选项告诉链接器使用 ELF (Executable and Linkable Format) 文件格式,并且生成 32 位 x86 架构的可执行文件。elf_i386
表示生成的可执行文件是面向 32 位 x86 架构的 ELF 文件。-s
: 这个选项用于剥离(strip)可执行文件中的符号表信息。符号表包含了程序中定义的各种符号(如变量、函数名等)的信息。在生产环境中,剥离符号表可以减小可执行文件的大小,但同时也会使得可执行文件不易调试。-o hello
: 这个选项指定生成的可执行文件的输出名称为hello
。-o
是指定输出文件的选项,后面跟着输出文件的名称。hello.o
: 这是输入的目标文件,它是由 NASM 编译器生成的,包含了汇编代码的机器代码。
- 最后通过
./hello
执行程序
文章来源:https://blog.csdn.net/m0_62264224/article/details/135048340
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!