在Linux上学习汇编语言
本学期开始学习计算机原理这门课程,决定在自己的试验机上搭建汇编程序的开发环境以利于相应知识的学习和实践
首先软件配置是 CentOS 7(64-bit) + Gnome ,我所学的汇编语言是 intel 风格的,编译器自然使用 nasm,可以通过 yum 来安装。除此之外还需要链接器,这里使用的是大部分 Linux 发行版都附带的 ld。调试器则是现后使用了自行下载编译的 ddd 和 kdbg (他们本质上其实都是对 GDB 做了带 GUI 的封装,至于为什么用两个,待会再提)。
参照 IBM 的Linux 汇编语言开发指南,先编写一个 HelloWorld.asm 的文本文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
; 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.
|
|
-
-f format
指定了输出文件的格式。 -
elf
是ELF32(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位二进制文件,否则会得到这个
1 |
ld: i386 architecture of input file `hello.o' is incompatible with i386:x86-64 output |
链接 object 文件生成可执行文件
1 |
ld -m elf_i386 -o hello hello.o |
有些教程中ld会带上 -s
参数,这样会删除 nasm 生产的符号表,然后就难以愉快地调试了。
可以直接运行二进制文件,不过我先试了一下 ddd
1 |
ddd hello |
ddd 不能显示汉字,又换成 kdbg。kdbg 需要 kde4 的支持,使用 yum 安装 kdelibs-devel 默认就是 kde4 的相关文件,使用 cmake 生成相应的 makefile,再用 make 编译安装
1 |
kdbg hello |