汇编基础之使用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 文件以及可执行文件具有正确的路径和权限。
相关推荐
xuanzdhc3 小时前
Linux 基础IO
linux·运维·服务器
愚润求学3 小时前
【Linux】网络基础
linux·运维·网络
bantinghy4 小时前
Linux进程单例模式运行
linux·服务器·单例模式
小和尚同志5 小时前
29.4k!使用 1Panel 来管理你的服务器吧
linux·运维
帽儿山的枪手5 小时前
为什么Linux需要3种NAT地址转换?一探究竟
linux·网络协议·安全
shadon1789 天前
回答 如何通过inode client的SSLVPN登录之后,访问需要通过域名才能打开的服务
linux
小米里的大麦9 天前
014 Linux 2.6内核进程调度队列(了解)
linux·运维·驱动开发
算法练习生9 天前
Linux文件元信息完全指南:权限、链接与时间属性
linux·运维·服务器
忘了ʷºᵇₐ9 天前
Linux系统能ping通ip但无法ping通域名的解决方法
linux·服务器·tcp/ip
成遇9 天前
在Vscode中安装Sass并配置
vscode·rust·sass