美文网首页
GNU 汇编: 第一个汇编程序

GNU 汇编: 第一个汇编程序

作者: wjundong | 来源:发表于2021-07-17 15:49 被阅读0次

介绍

汇编语言程序由定义好的段构成, 每个段都有不同的目的, 最常用的三个段如下

  • 数据段: 声明带有初始值得数据
  • bss 段: 声明使用 0 值初始化的数据元素
  • 文本段: 声明指令代码的地方, 其他段可能没有, 但文本段是必须的

定义段

.section 命令语句可声明段, .section 语句只有一个参数, 这个参数用来声明段的类型.

实例

获取 cupid 的程序: demo.s

.section .data

output:
    .ascii "The processor Vender ID is 'xxxxxxxxxxxx'\n"

.section .text
.globl _start

_start:

    // 获取 CPU ID
    movl $0, %eax
    cpuid
    
    // 将 CPU ID 填充到 output 的占位符部分
    movl $output, %edi
    movl %ebx, 28(%edi)
    movl %edx, 32(%edi)
    movl %ecx, 36(%edi)

    // 系统调用, 显示 CPUID
    movl $4, %eax
    movl $1, %ebx
    movl $output, %ecx
    movl $42, %edx
    int $0x80
    movl $1, %eax
    movl $0, %ebx
    int $0x80

    // 系统调用, 返回程序执行结果
    movl $1, %eax
    movl $0, %ebx
    int $0x80
    ret

上面程序程序声明了一个数据段文本段, 在数据段中使用 .ascii 声明了一个预定义的字符串, 其起始内存地址由标签 output 指示, 后面的 x 作为占位符以放置读到的cpuid.
.globl 命令用来声明外部程序可以访问的程序标签, _start 标签定义程序执行起始内存地址, 因为 ld 程序默认在链接时会去寻找 _start, 不过也可以通过 -e 参数更改默认的起始地址标签.
int $0x80 将生成具有 0x80 的软件中断, Linux 可利用该中断来进行系统函数调用, Linux 的 write 系统调用用于把字节写入文件, 其参数如下

  • EAX 包含系统调用值
  • EBX 包含要写入的文件描述符
  • ECX 包含字符串的开头
  • EDX 包含字符串的长度

Linux 一切皆文件, 因此 movl $1, %ebx 告诉系统调用 wirte 将信息输出到标准输出 STDOUT, 即控制台显示屏上.

通过系统调用 1 (退出函数), 程序被正确终止, 并返回到命令提示符, EBX 寄存器包含程序返回给 shell 的退出代码.

编译运行

  1. 使用 as 进行编译:

    $ as demo.s -32
    

    上面是 32 位程序, 如果是 64 位的电脑, 需要使用 -32 指定编译生成的是32位的程序.

  2. 使用 ld 进行链接:

     $ ld ./a.out -o demo -m elf_i386   
    

    同样 64 位的电脑链接 32 位程序需要使用 -m elf_i386 指示生成的可执行程序是 32 位类型的.

  3. 运行

     $ ./demo
     The processor Vender ID is 'GenuineIntel'
    

使用 gcc 直接编译

gcc 标签识别 main 标签, 更改 _startmain 然后执行:

$ gcc demo.s -m32
$ ./a.out
The processor Vender ID is 'GenuineIntel'

使用 WSL

如果使用的是 WSL, 64位的 WSL 环境默认无法编译运行32位程序, 可通过如下方案运行 (参考https://github.com/Microsoft/WSL/issues/2468):

  1. 安装 qemu and binfmt
     sudo apt update
     sudo apt install qemu-user-static
     sudo update-binfmts --install i386 /usr/bin/qemu-i386-static --magic '\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00' --mask '\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xf8\xff\xff\xff\xff\xff\xff\xff'
    
    并设置每次重启 WSL 都激活该功能
     sudo service binfmt-support start
    
  2. 接下来启用 i386 体系结构和 package
     sudo dpkg --add-architecture i386
     sudo apt update
     sudo apt install cpp-9:i386
     sudo apt install gcc:i386
    
  3. 设置开机启动
     vim /etc/myinit.sh
     sudo service binfmt-support start
    

相关文章

  • 在汇编语言中使用C库函数

    在 GNU 汇编: 第一个汇编程序 [https://www.jianshu.com/p/41ec925fffc8...

  • GNU 汇编: 第一个汇编程序

    介绍 汇编语言程序由定义好的段构成, 每个段都有不同的目的, 最常用的三个段如下 数据段: 声明带有初始值得数据 ...

  • 编写完整的汇编程序

    第一个完整的汇编程序 前面的实验都是利用Debug程序进行模拟测试的,并没有编写一个完整的汇编程序 使用汇编语言编...

  • Linux汇编初步

    安装软件 第一个汇编程序 编译,链接和执行程序。

  • 汇编程序基础

    汇编程序基础 一、汇编程序基本结构 二、汇编指令 1.汇编指令基本结构 三、伪指令 1.段定义 2.数据定义 数据...

  • C语言到汇编-入门

    上一篇已经得到了C语言入门程序对应的汇编程序。C语言程序: 编译后的汇编程序: 先看汇编程序的第一行: 好像没见过...

  • 这份pdf让我顺利的拿到了抖音的office

    RealView编译工具 汇编程序指南 本pdf提供相关RealView编译工具(RVCT)汇编程序的指导呵参考信...

  • 链接

    原文 1. 编译系统 预处理阶段:处理以 # 开头的预处理命令;编译阶段:翻译成汇编程序;汇编阶段:将汇编程序翻译...

  • 软件设计师考试 | 第二章 程序设计语言基础知识 | 语言处理程

    (一)汇编程序基本原理 1.汇编语言 汇编语言是为特定的计算机设计的面向机器的符号化的程序设计语言。汇编程序的分类...

  • 8086汇编-汇编程序、函数

    Hello World! 今天我们来编写第一个汇编程序,还是经典打印Hello world,这里我们在window...

网友评论

      本文标题:GNU 汇编: 第一个汇编程序

      本文链接:https://www.haomeiwen.com/subject/ceywpltx.html