汇编学习2019-10-20
一段内存,既可以是代码存储空间,又是数据的存储空间,还可以是栈空间,也可以设么也不是,它们主要取决于cpu中寄存器的设置
- CS(Code segment),IP(instruction pointer) :代码段
- SS(stack segment),SP(stack pointer) :栈段
- DS(date segment) :数据段
debug在修改寄存器ss时候,下一条指令也紧接着被执行例如:
1 | mov ss,ax |
汇编程序
汇编程源程序中有两类指令,一是汇编指令,第二是伪指令,汇编指令是有对应的机器码的指令,伪指令是由编译器来执行的。
目的 | 相关指令 | 指令性质 | 指令执行者 |
---|---|---|---|
通知某一寄存器和程序中的某个段相联系 | assume 寄存器:段名 | 伪指令 | 编译时,由编译期执行 |
通知编译器一个段开始 | 段名 segment | 伪指令 | 编译时,由编译期执行 |
通知编译器一个段结束 | 段名 ends | 伪指令 | 编译时,由编译期执行 |
程序返回 | mov ax,4c00H int 21H | 伪指令 | 编译时,由编译期执行 |
程序结束 | 段名 end | 伪指令 | 编译时,由mov编译期执行 |
EXE文件加载
-
找到一段起始地址为SA:0000的容量足够的空闲内存区(复习操作系统中寻找内存空间的相关内容)
-
在这段内存前256字节中,创建一个程序段前缀(PSP)的数据区,DOS要利用PSP来和被加载程序进行通信
-
从这段内存的256字节出开始(PSP后面),将程序装入,程序地址被设为
SA+10H:0
;空闲内存区: SA:0 PSP区: SA:0 程序区: SA+10H:0 - PSP区和程序区虽然物理地址连续,但是却有不同的段地址
- PSP头两个字节是 CD 20
程序装入,程序的地址被设为SA+10H:0 (其中SA为系统为程序分配内存的起始位置的段地址,这个段地址被存放在DS寄存器当中,所以,从DS寄存器中可以得到PSP的段地址 )因为PSP占256字节(100H),所以程序的物理地址为 SA16+256 --> SA16+16*16 --> (SA+16)*16 --> SA+10H;
debug后CS值比DS大10H,CS为代码段寄存器(程序区),DS为数据段(初始时==SA)
汇编文件编写及生成exe等文件
编写下列代码进入文件t1.asm
1 | cs:codesg |
- 注意上面的
add sp,10
10后面没有H(即不是10H),就代表这是十进制写法,sp=10–> sp=000a H
进行编译,链接 生成exe
1 | masm ti.asm; |
指令执行过程
push ax
是入栈指令,在执行push ax时,cpu先将 SP=SP-2
然后再将数据送入SS:SP
指向的内存单元
pop ax
是出栈指令,CPU先读取SS:SP
处的数据,再SP=SP+2
指令学习
inc
inc bx
含义是bx
中的内容加一
[bx]
[bx]
: 类比[idata]
的含义: DS中的数据段地址偏移量为idata处的值,则[bx]
含义为将bx中的值作为偏移(段地址存在DS中)
1 | mov ax,[bx] |
功能: bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将SA:EA处的数据送入ax中。即:((ds)*16+(bx))=(ax)
Loop
CPU执行Loop指令时要进行两步操作:
1. (cx)=(cx)-1
2. 判断cx中的值,不为零则转至标号处执行程序,如果为0则向下执行