汇编基础之使用vscode写hello world

汇编语言(Assembly Language)

概述

汇编语言(Assembly Language)是一种低级编程语言,它直接对应于计算机的机器代码(machine code),但使用了更易读的文本符号。每台个人计算机都有一个微处理器,用于管理计算机的算术、逻辑和控制活动。每个处理器系列都有其自己的指令集,用于处理各种操作,例如从键盘获取输入、在屏幕上显示信息以及执行各种其他任务。这些指令集称为"机器语言指令"。处理器仅理解机器语言指令,这些指令是由1和0组成的字符串。然而,机器语言过于晦涩难懂,难以在软件开发中直接使用。因此,低级汇编语言应运而生,它为特定的处理器家族设计,以符号代码和更易理解的形式表示各种指令。学习汇编语言虽然困难,但它能提供对计算机系统的深刻理解,提升编程效率和低级编程技能,并在安全、逆向工程、调试、编译器开发等领域提供重要帮助。(◉3◉)

我这里使用的是kali linux,后续的操作可能不同的操作系统会不一样

汇编器(Assembler)

将汇编语言代码转换为机器码的工具。这就类似于python,nodejs,gcc将py,js,c转化为机器码。汇编语言是针对特定计算机体系结构的低级编程语言,而大多数高级编程语言通常可跨多个系统移植。

接下来,你需要选择一个汇编语言编译器(或汇编器)。常用的汇编器包括:

  1. NASM (Netwide Assembler)
  2. GAS (GNU Assembler)
  3. MASM (Microsoft Assembler) - Windows平台上使用
  4. FASM (Flat Assembler)

这里推荐使用**NASM,**支持linux和windows,免费并且在网上的教程比较多。

其他操作系统可根据网址自行下载nasm下载

bash 复制代码
sudo apt-get update
sudo apt-get install nasm

基础语法

1. 段(Section)

汇编程序通常分为三个主要部分,分别是数据段、代码段和栈段。段(Section)是程序的逻辑分区,用于组织代码和数据。每个段通常具有特定的用途,如存储代码、数据或堆栈。

注释

汇编语言注释以分号(;)开头。它可以包含任何可打印字符,包括空格。它可以单独出现在一行上

bash 复制代码
section .data
    hello db 'Hello, World!', 0  ; 已初始化的数据

section .bss
    buffer resb 64  ; 未初始化的数据

section .text
    global _start

_start:
    ; 将 'Hello, World!' 输出到标准输出
    mov eax, 4         ; syscall number for sys_write
    mov ebx, 1         ; 文件描述符1是stdout
    mov ecx, hello     ; 指向消息的指针
    mov edx, 13        ; 消息长度
    int 0x80           ; 调用内核

    ; 退出程序
    mov eax, 1         ; syscall number for sys_exit
    xor ebx, ebx       ; 退出代码0
    int 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)

汇编语言中的指令是处理器执行的基本操作单元。每条指令通常由操作码和操作数组成。

bash 复制代码
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)

标签用于标识程序中的位置,便于跳转和调用,标签以冒号结尾。如下的两个标签

bash 复制代码
_start:
    mov eax, 1
    jmp _exit

_exit:
    mov eax, 60    ; 系统调用号(sys_exit)
    xor edi, edi   ; 退出状态码0
    syscall

5.系统调用

在Linux系统中,汇编程序通常通过触发中断(如int 0x80)或使用syscall指令进行系统调用。

vscode配置

安装拓展:

在拓展搜索:NASM

如果你只需要语法高亮,可以选择 The Netwide Assembler (NASM) highlightnasm x86 syntax highlighting

如果你需要更多的语言支持和调试功能,可以选择 NASM Language SupportNASM 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 可执行文件。
bash 复制代码
nasm -f elf32 -o hello.o hello.asm

ld -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 文件中:

bash 复制代码
{
    "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一样)管理这个文件夹下的文件,使用快捷命令会成功,但是使用别的文件夹没有做如上的配置快捷键是没有用的。注意每次都要配置好了

确保权限和路径正确

  • 确保 nasmld 命令在你的 PATH 环境变量中可用。
  • 确保你的 .asm 文件和生成的 .o 文件以及可执行文件具有正确的路径和权限。
相关推荐
颇有几分姿色9 分钟前
深入理解 Linux 内存管理:free 命令详解
linux·运维·服务器
AndyFrank40 分钟前
mac crontab 不能使用问题简记
linux·运维·macos
筱源源1 小时前
Kafka-linux环境部署
linux·kafka
算法与编程之美2 小时前
文件的写入与读取
linux·运维·服务器
xianwu5432 小时前
反向代理模块
linux·开发语言·网络·git
Amelio_Ming2 小时前
Permissions 0755 for ‘/etc/ssh/ssh_host_rsa_key‘ are too open.问题解决
linux·运维·ssh
Ven%3 小时前
centos查看硬盘资源使用情况命令大全
linux·运维·centos
TeYiToKu4 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
dsywws4 小时前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
yeyuningzi4 小时前
Debian 12环境里部署nginx步骤记录
linux·运维·服务器