在 Linux 上学习汇编语言

2015-09-10, 星期四, 00:00

本学期开始学习计算机原理这门课程,决定在自己的试验机上搭建汇编程序的开发环境以利于相应知识的学习和实践。

首先软件配置是 CentOS 7(64-bit) + Gnome,我所学的汇编语言是 intel 风格的,编译器自然使用 nasm,可以通过 yum 来安装。除此之外还需要链接器,使用的是大部分 Linux 发行版都附带的 ld。调试器则使用自行下载编译的 kdbg(本质上是 GDB 的 GUI 封装)。

参照 IBM 的 Linux 汇编语言开发指南,先编写一个 HelloWorld.asm 的文本文件。

; hello.asm
section .data            ; 数据段声明
        msg db "Hello, world!", 0xA     ; 要输出的字符串
        len equ $ - msg                 ; 字串长度
section .text            ; 代码段声明
global _start            ; 指定入口函数
_start:                  ; 在屏幕上显示一个字符串
        mov edx, len     ; 参数三:字符串长度
        mov ecx, msg     ; 参数二:要显示的字符串
        mov ebx, 1       ; 参数一:文件描述符(stdout)
        mov eax, 4       ; 系统调用号(sys_write)
        int 0x80         ; 调用内核功能
                         ; 退出程序
        mov ebx, 0       ; 参数一:退出代码
        mov eax, 1       ; 系统调用号(sys_exit)
        int 0x80         ; 调用内核功能

使用 nasm 编译,there’s always the manual.

nasm -f elf -g -F stabs hello.asm -o hello.o
  • -f format 指定了输出文件的格式。
  • elfELF32(i386 object file) 的简写。
  • 参数 -g 生产可用于调试工作的信息。
  • -F format 指定了调试信息的格式(debugging formats),有两个选择:stabs(symbol table)和 dwarf(debug with arbitrary record format)。具体可以看这篇Debugging formats DWARF and STAB

使用 ld 链接 object file,需要注意的是程序是以 32 位模式编译的(由 -f elf 参数指定),因此在 64 位系统中也要告诉链接器不要试图生成 64 位二进制文件,否则会得到

ld: i386 architecture of input file `hello.o' is incompatible with i386:x86-64 output

链接 object 文件生成可执行文件

ld -m elf_i386 -o hello hello.o

有些教程中 ld 会带上 -s 参数,这样会删除 nasm 生产的符号表,然后就难以调试了。

kdbg 需要 kde4 的支持,使用 yum 安装 kdelibs-devel 默认就是 kde4 的相关文件,使用 cmake 生成相应的 makefile,再用 make 编译安装

kdbg hello

kdbg