第四章
1.汇编程序中包含两种指令:伪指令与汇编指令
伪指令(类似于C语言中用#开头的语句):
assume cs:xxx (将寄存器与程序中的某个段相关联)
xxx segment : (段开始)
...
xxx ends (段结束)
end (整个程序的结束)
2.程序返回:
在DOS(一个单任务操作系统)中,某程序P2在可执行文件中,则必须有一个正在运行的程序P1,将P2从可执行文件载入内存,将CPU的控制权交给P2.P2开始后P1暂停运行,等到P2运行完毕后将控制权交还P1,P1再继续运行
汇编指令:
mov ax,4C00H或者mov ah,4ch
int 21H
3.DOS系统中,可执行文件由程序command.com(命令解释器,DOS系统的shell)执行
command 先将可执行文件的程序载入内存(由寄存器CX存放程序的长度),设置CS:IP指向程序的入口,此后command暂停运行,CPU运行程序.程序运行结束后,返回到command中,command才能继续运行等待用户的下一个输入
第五章
1.定义一个描述性的符号().(20000H)表示内存20000H单元(物理地址)的内容
即当ds=2000h时, [0] 与 (20000H)表示同一地址
()内也可以是含有寄存器和运算的地址
例如mov ax,[2] 可以用 (ax) = ( (ds)*16 + 2 )来描述
add ax,2可以用 (ax) = (ax)+2来描述
push ax可以用 (sp) = (sp)-2
((ss)*16+sp ) = (ax) 来描述
(X)表示的数据可以是字(8位,1b)或者字节型(16位,2b),具体是哪种类型由寄存器名或者具体的运算来决定
如 (al) = (20000H) 则 访问(20000H)得到的数据为字节型
若 (ax) =(20000H) 则访问得到的数据为字型
2.指令mov ax,[bx]是把寄存器bx中存放的数据作为一个偏移地址(设为EA),
段地址SA默认在ds中,将SA:EA这个地址的数据送入ax中,即(ax) = ((ds)*16+bx )
3.loop指令: loop 段名称
执行Loop的时候CPU执行两步: cx -= 1 ; 判断cx值若不为0则跳到标号处执行程序,若为0则向下执行
4.对于mov ax,[1]这条指令(注意[]内是idata) , debug会将它解释为mov ax,[1], 然而汇编编译器masm则会解释为movax,1即把[1]内的idata直接拿出来当做一个普通的常量,只会把mov ax,[bx]即用[]括起来的寄存器的值当做偏移地址.因此以防万一应该都把movax,[1]写成mov ax,[bx]的形式(事先mov bx,1)
补:其实masm中写成mov ax,ds:[1]的指令就会和debug中mov ax,[1]达到相同的效果
5.段前缀:显式地指明内存单元段地址,如mov ax,es:[bx]中的 ex:
6.一般的PC中在DOS方式下,DO和其他合法的程序都不会使用0:200~0:2ff (00200h~002ffh)这256个字节的空间,所以这段空间是安全的
7.0:200~0:20b 与 0020:0~0020:b描述的是同一段内存空间
8.在8086CPU中,只有bx,si,di,bp这4个寄存器可以用在[...]中来进行内存单元的寻址
第六章
1.
datasegment
dw0123h,0456h,0789h,0abch
assumecs:code, ds:data
定义了四个字型数据, 每个占2个字节(2*8bit),一共占8个字节(也可以说开辟了一段内存空间)
地址分别为ds:0, ds:2,ds:4, ds:6
2.加载完程序时若 DS=0B2D,则可推出程序(所有)代码(包括data段)从0B3D:0000开始存放 (有0x10h的一段内存用来存放PSP),即用-d查看会出现 0B3D:0000 23 01 56 04 89 07 BC 0A 00 00
上面即使data段的数据
3.mov ds,data是错误的,因为8086(16位)CPU不允许将一个一个数值直接送入段寄存器中
(因为该条指令的"data"被编译器处理为一个表示段地址的数值)
4.
不一定要设一个data 段来存放数据,也可以直接在code段中定义数据,
但这样数据就与代码存放在一起,程序会自动将入口设在定义的首个数据地址开始执行,此时的机器码是数据,不是想要执行的程序汇编代码,因此可能会出现错误
在这种情况下,在需要执行的代码开头加上一个段标如main:
并在code ends下一行加上 end main 即可告诉编译器要从main处开始执行
这条end与其他段的ends指令都不同