m汇编学习过程中用到的实例:
mov ax, 5807h | |
mov cx,9 | |
mov al, [0010h] | 虽然默认是DS段,但是没加DS的时候还是没有真正从存储器寻址,只好把DS加上了(根据后面的实验,如果不加段寄存器,会被当做立即数看待,和书上讲的还是有点差距奥)。 |
mov ax, [0010h] | 这里将把[0010h]计算出来的物理地址PA对应的数值赋给al,然后地址加一位置的数值赋给ax。 |
mov ax, DS: [0010h] | |
MOV bx, 0009h mov al, DS:[bx] | 寄存器间接寻址 |
MOV bx, 0009h mov ax, 0010H[BX+SI] | 基址变址寻址 |
计算指令的平均执行时间:
根据cpu的始终频率计算,计算指令的平均执行时间:
比如我的cpu时钟频率是2.8Ghz=> 单时钟周期为:0.357ns
【1s=1000ms=10(6)微s=10(9)ns】
【1Ghz=10(9)Hz】
还需要理解指令在不同寻址方式下的基本执行时间,以及对应的计算EA所需的周期数。
六类指令:1 传送指令
【1】数据传送指令: [立即数和段寄存器cs不能作为目的操作数;源操作数和目的操作数不能同为存储器操作器] | mov ax,bx; mov cl, 80h mov al, [2000h] |
mov DS:[0005h], ax | 我用的这个版本必须加DS,书上没有见。 这句话的意思是将ax当前的值移动到DS基地址偏移5h的位置,我们在debug中使用d命令查看时,直接 -d 0005就可以看到这个值是否和ax中一致【需要注意的是,d命令中输入的默认地址本来就是相对于段寄存器的偏移地址】 另外这里还可以是CS,ES,但是masm5中居然还不支持FS. |
MOV bx, 0001h mov SI, 0002h mov word ptr[bx+si], 88h | 这条命令就把DS:0003的位置的值赋为88h。由于这里用了word ptr,因此操作数的类型为字,因此是把0080H的值传送到偏移地址0003h处(0003被赋值为80h,同时0004被赋值为00h),如果是mov byte ptr[bx+si], 88h,就不会把0004赋值为00. |
mov ax,0a0bh mov bx,0c0dh mov cx,0e0eh push ax push bx push cx pop ax pop cx pop bx | 执行完前4句后,把ax放入堆栈中,就可以通过-d SS:[SP的值] 如sp=00fe,这里就是 -d ss:00fe 实际中不要加中括号,来查看栈顶的内容了,如果正常的话,就应该时0b 0a。 执行完pop ax后,ax就被赋值为cx的值了。同理cx=原bx的值;bx等于原ax的值。 实验结果表示同意。
|
xchg ax, bx | 会交换两个通用寄存器的值。
|
1.2 累加器专用传送指令 | |
XLAT | 把Bx与AL相加形成有效地址,将该单元中的单字节数传送到AL中 |
mov bx,4c02h mov al, 1dh xlat | 执行xlat时,根据xlat的定义,就会把bx+al=4c0f位置的值(单字节)送到AL,通过-d 4c0f发现此处是16,正是执行后al的值。 |
IN 累加器 端口地址 | 从指定地址输入一个字节到AL或输入一个字到AX, 端口地址以数值形式给出或者通过DX间接给出(端口地址大于255时,只能由DX给出) |
mov dx, 280h in al, dx | 运行时,debug直接退出了 |
out 端口地址 累加器 | 实现输出,与IN输入反方向数据传送 |
1.3 地址传送指令 |
|
LEA 目的操作数 源操作数 | 将源操作数的有效地址EA传送给通用寄存器 |
mov bx, 0408h mov si, 2000h LEA bp, [bx+si+6] | 将240EH送BP,而不是将此单元中的内容送BP。 |
LDS 目的操作数,源操作数 LDS SI, ES:[40H] | 将源操作数指定的存储单元中的双字(通常为段地址和有效地址)传送给DS及目的操作数,高两字节送DS,低两字节送目的操作数。 |
LES 目的操作数,源操作数 | 传送时将高两字节送ES,而不是送DS |
1.4 标志传送指令 | 专用于对标志寄存器进行操作。8086、8088标志寄存器具有16位,LAHF和SAHF仅对低8位操作,而PUSHF和POPF对整个标志寄存器操作。只有SAHF和POPF影响标志寄存器的内容。 |
LAHF | 将标志寄存器低8位送AH |
SAHF | 将AH送标志寄存器低8位 |
PUSHF | 将标志寄存器内容压入堆栈 |
2 算术运算指令:二进制算术指令运算指令和BCD数算术运算调整指令
mov al, 00eeh mov bl, 009eh ADD al, bl 对应的加法SUB: SUB al, bl | 很奇怪的一个现象,当我把eeh赋值给al时,居然不能识别,只好在前面加了两个00. |
mov dx, 2000h mov ax, 8a04h Add ax, 9D00h ADC ax, 45H 对应的减法SBB: | 主要用于多字节加法运算,dx存储了被加数的高两个字节, ax存储了低两字节;相加后ax=2704h,cf=1(相加结果 超过了两个字节)。adc实现高两字节的相加,且将cf价 值Dx,使DX为2046h。 SBB时同样减去执行前得CF值。 |
MOV si, 2000h MOV al, [SI] INC si ADD AL, [SI] 对应的减1 DEC | 实现了把2000h单元和2001单元的内容的相加,可以通过 -d 2000 查看。 但是INC(DEC)不影响CF标志。 |
NEG ax | 求补码(用0减去自身) |
CMP ax, bx | 如果一样,零标志为1 (zr) |
备注:
标志寄存器
溢出标志OF(Over flow flag) OV(1) NV(0)
方向标志DF(Direction flag) DN(1) UP(0)
中断标志IF(Interrupt flag) EI(1) DI(0)
符号标志SF(Sign flag) NG(1) PL(0)
零标志ZF(Zero flag) ZR(1) NZ(0)
辅助标志AF(Auxiliary carry flag) AC(1) NA(0)
奇偶标志PF(Parity flag) PE(1) PO(0)
进位标志CF(Carry flag) CY(1) NC(0)