前言
之前在读汇编语言_第四版 .pdf (wenjie.store),看到第二章的时候就有实操的部分了,但遗憾的是作者第4版(20年发版)的书还是用着8086的CPU,这就导致我手上的电脑无法跟着作者愉快的玩耍 (无法用公司电脑愉快摸鱼) ,于是整合了网上的一些方法,记录下如何装这个环境。
其实这篇教程在很早之前就写了,只是中间博客备案出了点问题,就丢到别的平台上了,现在才想起来有这么回事😂
使用DosBox
安装DosBox
首先先下载DosBox,选择对应的系统版本下载即可,如下图所示👇:
下载后双击打开.dmg
文件,界面如下所示👇:
之后新打开一个仿达
,把上面的DosBox
拖进应用程序(Application)
即可👇:
之后你就可以在启动台看见DosBox
了👇:
这里先不启动,因为启动了之后没东西挂载,下面我们先把masm的文件都下载下来了。
下载masm文件、挂载
下载完后,将文件都放到一个目录下,我自己的电脑用的是~/test/DosBox
,你也可以选择自己喜欢的目录,如下所示👇:
接着就是打开我们之前下载的DosBox
,打开后如下所示👇:
接下来就是用mount
命令挂载上面的~/test/DosBox
目录了,这里我挂为c
盘,命令如下所示👇:
- 出现上面这个提示就说明安装成功了
然后就是类似win的命令了,我们切到C盘,查看当前目录的文件👇:
到此安装完成了,接下来试试简单的命令。
输出helloworld
在之前挂载的目录里面增加一个hello.asm
,内容如下👇:
data segment
mes db 'Hello,World!' ,0DH ,0AH ,24H
; 0DH : 回车
; 0AH : 换行
; 24H : '$' ,即结束符号
data ends
code segment
; 伪指令,告诉汇编程序段地址要放到哪个段寄存器中
assume cs:code, ds:data
main:
; ds是段寄存器,无法直接赋值,需要一个寄存器过渡,这里取bx
mov bx,data
mov ds,bx
; 将mes的首地址传给dx
mov dx,offset mes
; 调用9号DOS功能,即打印
mov ah,9
int 21h
; 返回DOS,退出
mov ah,4ch
int 21h
code ends
end main
之后执行命令:
MASM.EXE hello;
LINK.EXE hello;
hello
最终效果如下👇:
警告无视就好,因为我们不需要用到栈段
DosBox虽然能最大程度的还原书上的场景(有些还原不到),但如果执行过程中出现错误就比较麻烦了,因为窗口里的内容无法复制,这意味着写错什么东西需要你手动把关键信息打一遍贴到搜索引擎。
使用nasm
安装nasm
mac下执行如下命令即可:
brew install nasm
输出helloworld
首先是写一个hello.asm
,不同于DosBox
的虚拟环境,nasm
是直接用mac的本地环境,所以对应代码也有比较大的变化,不过整体逻辑是相似的,这个倒可以放心。
hello.asm
代码如下👇:
; 数据段
section .data
msg db "Hello, world!", 0x0A
len equ $ - msg
section .text
; 指定函数入口
global _main
; 系统调用封装
kernel:
syscall
ret
; 自定义函数(不一定要叫main,这只是个人习惯,函数名只要ld时对应就行)
_main:
; 4 即调用write
; rdi则是句柄
; rsi则是要输出内容的buffer
; rdx则是内容的长度
mov rax, 0x2000004 ; syscall 4: write(
mov rdi, 1 ; fd,
mov rsi, msg ; buffer,
mov rdx, len ; size
call kernel ; )
; 1 即调用exit
; rdi可以看做返回码
mov rax, 0x2000001 ; syscall 1: exit(
mov rdi,0 ; retcode
call kernel ; )
之后执行nasm -f macho64 -o hello.o hello.asm
,编译后的.o
文件在当前目录👇
下一步就是link了,这里我选择用gcc
间接使用ld
,执行命令gcc hello.o -e _main
(警告无视就好),之后发现当前目录多了个a.out
,这个最终的可执行文件👇
不直接用ld的原因是ld命令的参数在不同版本的mac可能是不一样的,见StackOverFlow的第二个回答
最后我们只需要在当前目录执行./a.out
即可👇