汇编语句中定义变量

  • GAS(GNU Assembler)

    • 设计目标:GAS 是 GNU 工具链的一部分,设计用于与 GNU 编译器集合(GCC)紧密集成。它支持多种平台和处理器架构,包括 x86、ARM、MIPS 等。
    • 使用场景 :主要用于与 GCC 一起使用,编写嵌入式系统、操作系统内核、以及其他需要与 GCC 集成的低级编程任务。它的设计使得它适合与 GNU 工具链中的其他工具(如 ld 链接器)一起使用。
  • NASM(Netwide Assembler)

    • 设计目标:NASM 是一个专注于 x86 和 x86-64 架构的汇编器,设计简单,语法直观。它强调与现代汇编语言语法的一致性,并提供了丰富的宏功能。
    • 使用场景 :适用于需要对 x86 架构进行细粒度控制的任务,如编写操作系统、引导程序、以及其他需要直接控制硬件的低级编程。它可以单独使用,也可以与不同的工具链一起使用(如使用 ld 链接器或其他链接器)。

GNU 汇编器(GAS)和 NASM 汇编器在定义变量和数据的方式上有一些重要的区别。以下是这两种汇编器在定义变量时的一些主要区别:

1. 数据段(Section)

  • GNU 汇编器(GAS) 使用 .data, .bss, 和 .rodata 段来定义数据。
  • NASM 汇编器 使用 section .data, section .bss, 和 section .rodata 来定义数据。
示例:定义数据段

GAS

cpp 复制代码
.section .data
my_var: .long 0x12345678  ; 定义一个32位整数

.section .bss
uninit_var: .skip 4       ; 预留4字节空间

NASM

cpp 复制代码
section .data
my_var dd 0x12345678      ; 定义一个32位整数

section .bss
uninit_var resb 4         ; 预留4字节空间

2. 数据定义伪指令

  • GNU 汇编器(GAS) 使用 .byte, .short, .long, .quad, .fill 等伪指令。
  • NASM 汇编器 使用 db, dw, dd, dq, resb, resw, resd, resq 等指令。
示例:定义数据

GAS

cpp 复制代码
.section .data
byte_var: .byte 0x1       ; 定义一个字节
short_var: .short 0x1234  ; 定义一个16位整数
long_var: .long 0x12345678 ; 定义一个32位整数

NASM

cpp 复制代码
section .data
byte_var db 0x1           ; 定义一个字节
short_var dw 0x1234       ; 定义一个16位整数
long_var dd 0x12345678    ; 定义一个32位整数

3. 未初始化数据

  • GNU 汇编器(GAS) 使用 .bss 段来定义未初始化的数据。
  • NASM 汇编器 使用 section .bssresb, resw, resd, resq 来预留空间。
示例:未初始化数据

GAS

cpp 复制代码
.section .bss
buffer: .skip 1024         ; 预留1024字节的空间

NASM

cpp 复制代码
section .bss
buffer resb 1024           ; 预留1024字节的空间

4. 只读数据

  • GNU 汇编器(GAS) 使用 .rodata 段来定义只读数据。
  • NASM 汇编器 也使用 section .rodata 来定义只读数据。
示例:只读数据

GAS

cpp 复制代码
.section .rodata
message: .asciz "Hello, World!"  ; 定义一个以0结尾的字符串

NASM

cpp 复制代码
section .rodata
message db 'Hello, World!', 0    ; 定义一个以0结尾的字符串

5. 符号导出

  • GNU 汇编器(GAS) 使用 .global 指令将符号声明为全局。
  • NASM 汇编器 使用 global 指令将符号声明为全局。
示例:定义全局符号

GAS

cpp 复制代码
.section .data
.global my_var
my_var: .long 0x12345678

NASM

cpp 复制代码
section .data
global my_var
my_var dd 0x12345678

总结

  • 数据段声明 :GAS 使用 .section,NASM 使用 section
  • 数据定义伪指令 :GAS 使用 .byte, .short, .long, .fill,NASM 使用 db, dw, dd, resb 等。
  • 未初始化数据 :GAS 使用 .bss,NASM 使用 section .bssresb, resw, resd, resq
  • 只读数据 :GAS 使用 .rodata,NASM 使用 section .rodata
  • 全局符号 :GAS 使用 .global,NASM 使用 global

GAS示例代码:

linkage.h

cpp 复制代码
#ifndef _LINUX_LINKAGE_H
#define _LINUX_LINKAGE_H

#define ENTRY(name) \
  .globl name; \
  ALIGN; \
  name:

#endif

start.S

cpp 复制代码
.text
#include "linkage.h"

.section ".data.pg_dir","w"
ENTRY(swapper_pg_dir)
    .long 100
    .fill 1023,4,0

main.c

cpp 复制代码
#include <stdio.h>

// 声明swapper_pg_dir符号,它在外部定义
extern unsigned int swapper_pg_dir[];

int main() {
    // 输出swapper_pg_dir的地址
    printf("Address of swapper_pg_dir: %p\n", swapper_pg_dir);
    // 访问swapper_pg_dir中的第一个值(应该是0)
    printf("First value in swapper_pg_dir: %u\n", swapper_pg_dir[0]);
    return 0;
}

gcc -c start.S -o start.o
gcc -c main.c -o main.o
gcc start.o main.o -o test

执行结果:

./test

Address of swapper_pg_dir: 0x55e20ee01010

First value in swapper_pg_dir: 100

代码解释

cpp 复制代码
.section ".data.pg_dir","w"
.globl swapper_pg_dir
swapper_pg_dir:
    .long 100
    .fill 1023,4,0
1. .section ".data.pg_dir","w"
  • .section :这条伪指令指定当前段的名称为 .data.pg_dir,并且该段是可写的("w")。如果你使用 ".data" 作为段名,它将是 .data 段的一个变体,但在此示例中,.data.pg_dir 是一个自定义段名。
  • .data 段通常用于已初始化的数据,但自定义名称可以用于组织不同类型的数据。
2. .globl swapper_pg_dir
  • .globl :这条伪指令将 swapper_pg_dir 符号声明为全局符号,使其可以在其他文件或模块中引用。
3. swapper_pg_dir:
  • swapper_pg_dir: :定义了一个标签 swapper_pg_dir,用于在内存中标识数据的开始位置。
4. .long 100
  • .long :将一个32位的整数 100 存储在 swapper_pg_dir 标签所在的内存位置。
5. .fill 1023,4,0
  • .fill :用于在内存中填充数据。
    • 1023:填充的数量,即填充 1023 个 4 字节(总共 4092 字节)的数据。
    • 4:每个填充项的大小,以字节为单位,这里是 4 字节。
    • 0:填充的值,这里是 0。
相关推荐
JCBP_17 小时前
QT(4)
开发语言·汇编·c++·qt·算法
sheepwjl2 天前
《嵌入式硬件(十二):基于IMX6ULL的时钟操作》
汇编·arm开发·单片机·嵌入式硬件·时钟·.s编译
DebugKitty2 天前
硬件开发2-ARM裸机开发1-I.MX6ULL - 汇编点灯
汇编·makefile·imax6ull·gpio·电路复用
我菜就多练2 天前
ARM-汇编的基础知识
汇编·arm开发
(Charon)2 天前
函数之间跳转的实现方式详解:setjmp/longjmp、ucontext 与汇编
汇编
起个昵称吧3 天前
立即数、栈、汇编与C函数的调用
c语言·开发语言·汇编
mysla5 天前
嵌入式学习day46-硬件—汇编
汇编·学习
zgc12453675 天前
汇编基础2
汇编
出门吃三碗饭5 天前
编译器构造:从零手写汇编与反汇编程序(一)
android·汇编
JCBP_5 天前
QT(3)
开发语言·汇编·c++·qt·算法