软件模拟环境

DOSBox

这是一个模拟dos系统的软件, 默认是w32位的操作系统

emu8086

这是一个模拟8086cpu的软件, 可以在上面编写汇编代码, 配有debug调试器

Debug

这是一个查看寄存器和更改寄存器以及单步调试指令的软件, 本次学习中在8086cpu上使用

  • R: 查看, 改变CPU寄存器的内容

  • D: 查看内存中的内容

  • E: 改写内存中的内容

  • U: 将内存中的机器指令翻译成汇编指令

  • T: 执行一条机器指令

  • A: 以汇编指令的格式在内存中写入一条机器指令

Debug 在执行T命令时, 如果当前执行的下一条执行是修改ss寄存器, 那么会一起执行

知识

栈在内存中的样子, 高位在下面, 低位在上面
栈在内存中的样子, 高位在下面, 低位在上面

在学习汇编前, 在高级语言中就经常使用栈操作: push和pop, 但通常是对"数组"进行"栈"操作, 数组在内存中通常确实是连续的内存地址, 我们也确实在操作栈但很少或根本不会细想这些操作会对内存造成何种影响, 这也是学习底层语言的一种目的:为了知道自己在做什么, 这及其重要, 只有知道自己的每一行代码真正在内存中做了什么, 心智负担才能不因未知而增大, 这种确定感和掌控感是每位coder都应体验的

任意时刻CS:IP指向将要执行的指令
任意时刻SS:SP指向栈顶

栈空时, SP指向栈最高位地址单元的下一位单元, 因为当栈中有一个字单元时, SP指向max-1, 那么pop掉这个字单元时, SP+2=max+1

栈段的长度是由SS和SP决定的,

比如SS为1000H,SP为0020H,那么栈段就为10000H-10001FH
比如SS为2000H,SP为0010H,那么栈段就为20000H-20000FH

入栈

push ax指令做的事情:

先改变SP的值, 变为: SP=SP-2

这时记住栈顶地址:SS:SP

再将ax的值放入SS:SP执行的物理内存地址

出栈

pop ax指令做的事情

先将SS:SP的值放入寄存器ax

再将SP+2, 以SS:SP为新的栈顶

注意:出栈时栈顶元素并没有消失, 只是不在栈中了, 当再次push时该栈顶元素将被覆盖

第一个汇编程序

1
2
3
4
5
6
7
8
9
10
11
12
13
assume cs:codesg

codesg segment
mov ax,0123H
mov bx,0456H
add ax,bx
add ax,ax

mov ax,4c00H
int 21H
codesg ends

end