汇编语言(Assembly Language)
概述
汇编语言(Assembly Language)是一种低级编程语言,它直接对应于计算机的机器代码(machine code),但使用了更易读的文本符号。每台个人计算机都有一个微处理器,用于管理计算机的算术、逻辑和控制活动。每个处理器系列都有其自己的指令集,用于处理各种操作,例如从键盘获取输入、在屏幕上显示信息以及执行各种其他任务。这些指令集称为“机器语言指令”。处理器仅理解机器语言指令,这些指令是由1和0组成的字符串。然而,机器语言过于晦涩难懂,难以在软件开发中直接使用。因此,低级汇编语言应运而生,它为特定的处理器家族设计,以符号代码和更易理解的形式表示各种指令。学习汇编语言虽然困难,但它能提供对计算机系统的深刻理解,提升编程效率和低级编程技能,并在安全、逆向工程、调试、编译器开发等领域提供重要帮助。(◉3◉)
我这里使用的是kali linux,后续的操作可能不同的操作系统会不一样
汇编器(Assembler)
将汇编语言代码转换为机器码的工具。这就类似于python,nodejs,gcc将py,js,c转化为机器码。汇编语言是针对特定计算机体系结构的低级编程语言,而大多数高级编程语言通常可跨多个系统移植。
接下来,你需要选择一个汇编语言编译器(或汇编器)。常用的汇编器包括:
- NASM (Netwide Assembler)
- GAS (GNU Assembler)
- MASM (Microsoft Assembler) - Windows平台上使用
- FASM (Flat Assembler)
这里推荐使用NASM,支持linux和windows,免费并且在网上的教程比较多。
其他操作系统可根据网址自行下载nasm下载
sudo apt-get update
sudo apt-get install nasm
基础语法
1. 段(Section)
汇编程序通常分为三个主要部分,分别是数据段、代码段和栈段。段(Section)是程序的逻辑分区,用于组织代码和数据。每个段通常具有特定的用途,如存储代码、数据或堆栈。
注释
汇编语言注释以分号(;)开头。它可以包含任何可打印字符,包括空格。它可以单独出现在一行上
section .datahello db 'Hello, World!', 0 ; 已初始化的数据section .bssbuffer resb 64 ; 未初始化的数据section .textglobal _start_start:; 将 'Hello, World!' 输出到标准输出mov eax, 4 ; syscall number for sys_writemov ebx, 1 ; 文件描述符1是stdoutmov ecx, hello ; 指向消息的指针mov edx, 13 ; 消息长度int 0x80 ; 调用内核; 退出程序mov eax, 1 ; syscall number for sys_exitxor ebx, ebx ; 退出代码0int 0x80 ; 调用内核
1 .data
段
- 用途:存储已初始化的全局和静态变量。
- 特性:可读写段,程序可以在运行时修改该段的数据。
- 典型内容:字符串、已初始化的变量和常量。
2 .bss
段
- 用途:存储未初始化的全局和静态变量。
- 特性:该段在程序加载时被清零,因此初始值为0。
- 典型内容:未初始化的变量,通常在程序开始时被初始化。
3 .text
段
- 用途:存储程序的可执行代码。
- 特性:该段通常是只读的,防止在运行时意外修改代码。
- 典型内容:函数、指令和跳转标签。
hello db 'Hello, World!', 0
:定义了一个名为 hello
的字节数组,存储字符串 "Hello, World!",以 null 字符(0)结尾。
global _start
:定义 _start
为全局符号,使得链接器知道程序从 _start
标签开始执行。
_start:
:程序的入口点,汇编程序从这里开始执行
2. 指令(Instruction)
汇编语言中的指令是处理器执行的基本操作单元。每条指令通常由操作码和操作数组成。
mov eax, 1 ; 将立即数1加载到寄存器eax
add eax, ebx ; 将寄存器ebx的值加到eax
int 0x80 ; 触发中断0x80,调用内核功能
3. 寄存器(Register)
寄存器是CPU内部用于临时存储数据的高速存储器。常见的寄存器有通用寄存器(如eax、ebx、ecx、edx)、段寄存器(如ds、es、fs、gs)、指针寄存器(如esp、ebp)等。
4. 标签(Label)
标签用于标识程序中的位置,便于跳转和调用,标签以冒号结尾。如下的两个标签
_start:mov eax, 1jmp _exit_exit:mov eax, 60 ; 系统调用号(sys_exit)xor edi, edi ; 退出状态码0syscall
5.系统调用
在Linux系统中,汇编程序通常通过触发中断(如int 0x80)或使用syscall指令进行系统调用。
vscode配置
-
安装拓展:
在拓展搜索:NASM
如果你只需要语法高亮,可以选择 The Netwide Assembler (NASM) highlight 或 nasm x86 syntax highlighting。
如果你需要更多的语言支持和调试功能,可以选择 NASM Language Support 或 NASM X86 Assembly Language。
如果你希望集成编译和运行功能,可以选择 nasm-compiler-linux。
-
创建文件:
在 VSCode 中创建一个新的文件,命名为 hello.asm
,并将之前的汇编代码粘贴进去。在上面哦
-
汇编代码:
在终端中,导航到包含 hello.asm
文件的目录,然后运行以下命令进行汇编:
1. nasm -f elf32 -o hello.o hello.asm
作用:使用 NASM(Netwide Assembler)编译汇编源文件 hello.asm
生成目标文件 hello.o
。
nasm
:调用 NASM 汇编器。-f elf32
:指定生成的目标文件格式为 32 位 ELF(Executable and Linkable Format),这是 Linux 上常用的目标文件格式。-o hello.o
:指定输出文件名为hello.o
。hello.asm
:输入的汇编源文件名。
2. ld -m elf_i386 -o hello hello.o
作用:使用链接器 ld
将目标文件 hello.o
链接成可执行文件 hello
。
ld
:调用链接器。-m elf_i386
:指定链接的目标为 32 位 ELF 格式(即 i386 架构)。-o hello
:指定输出文件名为hello
。hello.o
:输入的目标文件名。
3. ./hello
作用:运行生成的可执行文件 hello
。
./hello
:运行当前目录下的hello
可执行文件。
nasm -f elf32 -o hello.o hello.asmld -m elf_i386 -o hello hello.o./hello
如图所示,完成这步就可以输出hello world了。但是这样每次输入都很麻烦
快捷配置
-
创建任务配置文件: 在 VSCode 中,按下
Ctrl+Shift+P
,输入Tasks: Configure Task
,选择Create tasks.json file from template
,选择Others
。 -
编辑
tasks.json
文件: 将以下内容粘贴到tasks.json
文件中:
{"version": "2.0.0","tasks": [{"label": "Build, Link and Run","type": "shell","command": "bash","args": ["-c","nasm -f elf32 -o ${fileDirname}/${fileBasenameNoExtension}.o ${file} && ld -m elf_i386 -o ${fileDirname}/${fileBasenameNoExtension} ${fileDirname}/${fileBasenameNoExtension}.o && ${fileDirname}/${fileBasenameNoExtension}"],"group": {"kind": "build","isDefault": true},"problemMatcher": []}]
}
说明
- label: 任务的标签,这里命名为 "Build, Link and Run"。
- type: 设置为 "shell",表示在 shell 中执行命令。
- command: 设置为 "bash",用于在 Linux 环境中执行一系列命令。
- args: 参数部分,这里使用
bash -c
执行一连串的命令。包括编译、链接和运行三个步骤,使用&&
确保每一步成功后才执行下一步。 - group: 配置任务组,这里将其设置为默认的构建任务。
按 Ctrl+Shift+B
,选择 "Build, Link and Run" 任务来一键运行整个过程(我是按下后直接执行了的)。
这样,执行这个任务时,它会依次编译汇编代码、链接生成的目标文件并运行生成的可执行文件。
注意:这样做会生成.vscode,(像.git一样)管理这个文件夹下的文件,使用快捷命令会成功,但是使用别的文件夹没有做如上的配置快捷键是没有用的。注意每次都要配置好了
确保权限和路径正确
- 确保
nasm
和ld
命令在你的 PATH 环境变量中可用。 - 确保你的
.asm
文件和生成的.o
文件以及可执行文件具有正确的路径和权限。