0%

Windows10下搭建汇编语言开发环境

Windows10下搭建汇编语言开发环境

前言

本学期学校安排有汇编语言这门课,需要自己搭建汇编语言开发环境,特此写下本文记录搭建过程.

关于搭建汇编语言开发环境的教程,我也找了许多,可看下来却依旧一头雾水,经过本人摸索,同时结合网上教程,欲写下这篇易懂的文章.

准备工作

1.下载DOSBox

工具介绍:DOSBox是一个DOS模拟程序,由于它采用的是SDL库,所以可以很方便的移植到其他的平台.目前,DOSBox已经支持在Windows、Linux、Mac OS X、BeOS 、palmOS、Android 、webOS、os/2等系统中运行.不少DOS下的游戏都可以直接在该平台上运行.

工具官网:

工具官网

项目主页:

项目主页

下载链接1(32位):

下载链接1

下载链接2(这个是我下载好的,可能会快一点):

下载链接2

2.下载汇编工具包

下载链接:

下载链接

汇编工具截图

安装教程

1.安装DOSBox

双击运行DOSBox安装程序

点击next

点击next

选择安装位置(我选择都是D:\DOSBox)然后点击install即可

安装位置要记得,后面要用

2.创建工作目录

安装完毕创建一个工作目录(目录位置及目录名可自定义)

我的是在D:/DOSBox/Debug

之后再在Debug下创建两个文件夹ASM(放自己写的汇编程序)和MASM(放汇编工具)

将汇编工具放入MASM文件夹

3.挂载工作目录

打开DOSBox安装目录(我的在D:\DOSBox)

打开后找到DOSBox 0.74 Options.bat这个批处理文件

直接双击运行会出现一个记事本

使用快捷键Ctrl+F查找其中的[autoexec]部分(一般在文件末尾)

在文件中添加下列内容并保存

MOUNT F D:\DOSBox\Debug
set PATH=%PATH%;F:\MASM;
F:
cd F:\ASM
cls

命令解释:

#挂载工作目录挂载到虚拟盘符F(虚拟盘符可自定义,命令不区分大小写)
MOUNT F D:\DOSBox\Debug
#添加系统临时变量(此时的F代表的是D:\DOSBox\Debug)
set PATH=%PATH%;F:\MASM;
#转到F盘符
F:
#切换到F:\ASM目录
cd F:\ASM
#执行一次清屏
cls

如果不加cls,打开会是这样

加上cls,打开会是这样(我觉得更美观,依个人喜好)

注意:不进行此种配置的话,每次打开DOSBox是需要手动输入上述命令,非常麻烦

使用说明

DOSBox常用快捷键

快捷键 作用
Alt+Enter 切换全屏
Ctr+F1 改变键盘映射
Alt+Pause 暂停模拟
Ctrl+Alt+F5 开始/停止录制视频
Ctrl+F4 交换挂载的磁盘映像,也就是更新磁盘文件
Ctrl+F5 截图
Ctrl+F6 开始/停止录制声音
Ctrl+F7 减少跳帧
Ctrl+F8 增加跳帧
Ctrl+F9 关闭DOSBOX
Ctrl+F10 捕捉/释放鼠标
Ctrl+F11 模拟减速
Ctrl+F12 加速模拟
Alt+F12 不锁定速

注意:以上快捷键我并没有全部测试,更多详细信息参见README.txt(在DOSBox安装目录中的Documentation里面)

调整窗口大小

初始的界面很小,且不能直接拉伸界面,所以有需要的可以按照下面的方法调整一下
双击打开DOSBox 0.74 Options.bat

使用快捷键Ctrl+F查找windowresolution字段

windowresolution=original
output=surface

改为

windowresolution=800x500  #800x500为自定义大小,可修改
output=opengl

注意:不用删除原来的语句,在前面加上#注释掉即可

保存后,重启DOSBox生效

创建并编辑文件

关于创建并编辑文件,如果你的工作目录(挂载的目录)有EDIT.COM文件(我提供的汇编工具包中有),那么你就可以在DOSBox中创建并编辑文件,如果没有请使用我提供的工具包或者耐心往下看.

使用DOSBox创建并编辑文件(不推荐)

打开DOSBox使用下面命令创建并编辑test.asm文件

edit test.asm

回车后进入下面界面即可进行编辑(注意:鼠标箭头只能在编辑器里活动,想将鼠标退出来的话可以用Ctrl+F10组合键退出)

使用记事本创建并编辑文件(其他编辑器也可以)

下面以此种方式创建test.asm文件

新建文本文档,将下面代码复制到里面并保存

datas segment
buf db'Hello, World!$'
datas ends

stacks segment stack
db 200 dup(0)
stacks ends

codes segment
assume cs:codes,ds:datas,ss:stacks
start:
mov ax,datas
mov ds,ax

mov dx,seg buf
lea dx,buf
mov ah,09h
int 21h

mov ah,4ch
int 21h
codes ends
end start

之后重命名为test.asm

编译调试

打开DOSBox输入下面命令

masm test.asm

回车后会询问文件名,建议直接回车

编译程序提示输入交叉引用文件的名称,这个文件同列表文件一样,是编译器将源程序编译为目标文件过程中产生的中间结果.可以让编译器不生成这个文件,直接按Enter键即可

image-20210225195117402

可以像上图一样分别输入文件名,打开ASM查看如下

本文全部默认即不分别输入文件名直接回车

打开ASM文件夹查看如下

继续输入命令

link test.obj

运行完毕,查看ASM文件夹

继续执行下列命令

debug test.exe

自动编译调试

在实践过程中,如何你修改了text.txt(假设是创建的汇编代码文件),那么你就需要重新键入上述命令

masm test.txt
link test.obj
debug test.exe

非常的麻烦,因此我用我现学的批处理知识实现自动完成这些过程,解放双手.

实现过程

详细过程如下:

在MASM文件夹下创建run.txt(名字自定义)

打开run.txt,写入下面内容

@echo off
masm %1.txt;
echo *****************************
echo Compilation completed!
echo *****************************
link %1;
echo *****************************
echo Link completed!
echo *****************************
echo Start debugging!
echo *****************************
debug %1.exe

保存,重命名修改后缀.txt为.bat即可

实际使用

以汇编文件t8.txt为例

在ASM文件夹创建汇编文件t8.txt(注意后缀必须是.txt)

打开DOSBox,键入下列命令即可

run t8

run是刚才创建的run.bat,t8是汇编文件t8.txt

可见已经进入debug,并且ASM文件夹中也产生了.obj文件和.exe文件

debug的简单使用

debug是Dos、Windows提供的实模式(8086方式)程序的调试工具

  • 可以查看CPU各种寄存器的内容
  • 可以查看内存的情况
  • 可以在机器码级别跟踪程序的运行
命令 作用
R命令 查看、改变CPU寄存器的内容
D命令 查看内存中的内容(机器指令形式)(以16进制显示)
E命令 改写内存中的内容,即提供指令(使用机器指令),用得比较少,多为A命令
U命令 查看内存中的内容(将机器指令形式转换为汇编指令的形式)(反编译)
T命令 执行一条汇编(机器)指令(就是执行当前指令缓冲器中的指令)
A命令 相比较E,以汇编指令形式在内存写入一条机器指令
P命令 执行汇编程序,单步跟踪.与T命令不同的是:P命令不会跟踪进入子程序或软中断;还可以用于结束本次循环,进入下一次循环
G命令 执行汇编指令,不过和T指令不同的是,G指令不是逐条执行,而是一次性执行多条
Q命令 退出debug
?命令 查看指令帮助

R命令

查看CPU寄存器的内容

标识名 置位 复位
溢出Overflow(是否) OV NV
向Direction(减量/增量) DN UP
中断Interrupt(允许/屏蔽) EI DI
符号Sign(负正) NG PL
零Zero(是否) ZR NZ
辅助进位Auxiliary Carry(是否) AC NA
奇偶Parity(偶奇) PE PO
进位Carry(是否) CY NC
改变CPU寄存器的内容
改变寄存器的值

若要修改一个寄存器中的值,比如AX中的值,可用R命令后加寄存器名来进行,输入”r ax”后按Enter键,将出现”:”作为输入提示,在后面输入要写入的数据后按Enter键(直接按Enter则退出修改),即完成了对AX中内容的修改.若想看一下修改的结果,可再用R命令查看(R命令与寄存器名之间也可以没有空格)

改变CS:IP的值

改变标志位的值
rf

D命令

使用D命令,可以查看内存中的内容,debug将输出3部分内容:

  1. 中间是从指定地址开始的128个内存单元的内容,用16进制的格式输出,每行的输出从16的整数倍的地址开始,最多输出16个单元的内容.注意在每行的中间有一个”-“,它将每行的输出分为两部分,这样便于查看
  2. 左边是每行的起始地址
  3. 右边是每个内存单元中的数据对应的可显示的ASCII码字符.若没有对应可显示的ASCII字符,debug就用”.”来代替

注意,我们看到的内存中的内容,在不同的计算机中是不一样的,也可能每次用
Debug看到的内容都不相同,因为我们用Debug看到的都是原来就在内存中的内容,这些内容受随时都有可能变化的系统环境的影响.当然,我们也可以改变内存、寄存器中的内容

在一进入debug后,用D命令直接查看,将列出debug预设的地址处的内容

使用d 段地址:偏移地址查看(以d 1000:0为例)

格式:d 段地址:偏移地址
使用"d 段地址:偏移地址"的格式来查看,debug将列出从指定内存单元开始的128个内存单元的内容

在使用”d 段地址:偏移地址”之后,接着使用D命令,可列出后续的内容

也可以指定D命令的查看范围,此时采用”d 段地址:起始偏移地址 结尾偏移地址”的格式

若输入的地址不是16的倍数,则输出效果是这样的

E命令

改写内存中的内容,但是是以机器指令的形式

将内存1000:0-1000:9单元中的内容分别写为0、1、2、3….、9,可以用”e 段地址:起始地址 数据 数据 数据$\cdots $”的格式来进行

用E命令以提问的方式来逐个地修改从某一地址开始的内存单元中的内容

  • 红色部分为用户输入的修改的数据,到了某一内存单元的时候,可以选择修改(输入要修改的数值),也可以选择不修改(直接按空格),处理完一个内存单元之后,按空格,继续处理下一个内存单元;全部都处理完毕之后,按enter

可以用E命令向内存中写入字符

也可以用E命令向内存中写入字符串

U命令

对机器代码反汇编显示,U命令的显示输出分为3部分,每一条机器指令的地址、机器指令、机器指令所对应的汇编指令

按地址反汇编
u 地址

该命令从指定地址开始,反汇编32个字节,若地址省略,则从上一个U命令的最后一个指令的下一个单元开始显示32个字节

按范围反汇编
u 范围

T命令

命令格式
T [=地址] [指令数]

使用T命令执行CS:IP指向的指令

首先用E命令向从1000:0开始的内存单元中写入了8个字节的机器码

e 1000:0 b8 01 00 b9 02 00 01 c8
机器码 对应的汇编指令
b80100 mov ax,0001
b90200 mov cx,0002
01c8 add ax,cx

然后用R命令查看CPU中寄存器的状态,可以看到,CS=0740H、IP=0100H,指向内存0740:0100

若要用T命令控制CPU执行我们写到1000:0 的指令,必须先让CS:IP指向1000:0;接着用R命令修改CS、IP中的内容,使CS:IP指向1000:0

完成上面的步骤后,就可以使用T命令来执行我们写入的指令了(此时,CS:IP 指向我们的指令所在的内存单元).执行T命令后,CPU执行CS:IP指向的指令,则1000:0处的指令b8 01 00(mov ax,0001)得到执行,指令执行后,Debug 显示输出CPU中寄存器的状态

注意:指令执行后,AX中的内容被改写为1,IP改变为IP+3(因为mov ax,0001的指令长度为3个字节),CS:IP指向下一条指令

继续使用T命令执行下面的指令

用T命令继续执行后面的指令,注意每条指令执行后,CPU相关寄存器内容的变化

A命令

使用E命令写入机器指令很不方便,最好能直接以汇编指令的形式写入指令.为此,Debug 提供了A命令,A命令以汇编指令的形式在内存中写入机器指令

首先用A命令,以汇编语言向从1000:0开始的内存单元中写入了几条指令,然后用D命令查看A命令的执行结果

可以看到,在使用A命令写入指令时,我们输入的是汇编指令,Debug将这些汇编指令翻译为对应的机器指令,将它们的机器码写入内存

使用A命令写入汇编指令时,在给出的起始地址后直接按Enter键表示操作结束

若A命令后不跟地址,则从预设地址开始输入指令

P命令

在遇到汇编指令为int xx 时,使用p指令结束(否则CPU会指向一个未知的地址段)

在遇到loop循环时,可用p命令执行,debug会自动重复执行循环中的指令,直到cx=0为止,以下面程序为例

assume cs:code
code segment
mov ax,236
mov cx,122
s:add ax,ax
loop s

mov ax,4c00H
int 21H
code ends
end

G命令

G命令的使用方法是:

G[=起始地址] [断点地址]

意思是从起始地址开始执行到断点地址.如果不设置断点,则程序(从CS:IP)一直运行到中止指令才停止

?命令

输入?查看更多命令

结果如下:

-------------本文结束感谢您的阅读-------------