📄 lt57-1.asm
字号:
;例题5.7:P172 冒泡法实现数据排序。无序数组实现由大到小排序。
;题意分析:取第一个数放在AX中,和下一个的数比较,小的数放在下面(最高地址),
;大的数上升,第一个循环后,使最小的数排在最下面(最高地址)。
;同理进行第二次循环,查找的数据长度减一。
;多重循环:LT57-1·ASM采用最自然的减法。为每个循环设置一个循环计数器。
;每一次循环,将最小的数放在最底端(地址较大处)。
;程序中注意1·循环次数的确定。2·加深对指令LOOP的理解,指令XCHG的理解,指令XCHG
;与MOV DI,AX, MOV AX,[BX+HEAD+2]; MOV [BX+HEAD+2],DI;三条指令功能相同。
;该例题还可以改编成:数据区的数组HEAD有N个无序字数据,将数组HAED传送到数组SORT并
;且由大排序。
DATAREA SEGMENT; 定义数据段及数据分配。
HEAD DW 11H,22H,44H,66H,55H,00H,0FFH,03H; 全部是无符号数。
DW 88H,04H,33H,77H,99H,12H,13H, 0CCH; 第16个数不参加排序。
DW 8 DUP (0FFFFH); 为了调试时观察数据区方便
M_COUNT DW 15
N EQU 10
DATAREA ENDS;
PROGNAM SEGMENT; 定义程序段及程序段名。
MAIN PROC FAR
ASSUME CS:PROGNAM,DS:DATAREA; 段分配。
START:
PUSH DS; DOS调用要求。保护旧数据段DS,
SUB AX, AX; AX清零进堆栈保护,
PUSH AX;
MOV AX, DATAREA; DS数据段赋值。
MOV DS, AX;
MOV DX, M_COUNT; 数据字长度即循环次数给DI
MOV CX, DX; 求实际循环次数。CX作为里层循环计算器。
DEC DX; DX作为外层循环计数器,计数器赋初值。
LOOP1:
MOV CX, DX;
MOV BX, 00; BX作为数据指针,赋初值0。
LOOP2:
MOV AX, [BX+HEAD]; 取第一个数给AX。
CMP AX, [BX+HEAD+2]; AX中的内容和下一个字比较。
JAE COTINUE; AX大于第二个数转跳,数据区是无符号数,有符号数JGE
XCHG AX, [BX+HEAD+2]; 如果小于,进行交换,大的数放低字节,
MOV [BX+HEAD], AX; 小的数放高字节。(下一个单元地址)
COTINUE:
ADD BX, 02; BX加2,指向下一个字。
DEC CX;
JNZ LOOP2; 如果CX不等于0,转跳到LOOP2。
;LOOP LOOP2; (LOOP在逻辑上完全等同DEC CX、JNZ )
DEC DX; 修改外循环次数。
JNZ LOOP1; 如果DX不等于0,转跳到LOOP1。
RET;
MAIN ENDP;
PROGNAM ENDS;
END START;
-G 09
AX=13C0 BX=0000 CX=0071 DX=0000 SP=FFFC BP=0000 SI=0000 DI=0000
DS=13C0 ES=13B0 SS=13C0 CS=13C4 IP=0009 NV UP EI PL ZR NA PE NC
13C4:0009 8B163000 MOV DX,[0030] DS:0030=000F
-D DS:0
13C0:0000 11 00 22 00 44 00 66 00-55 00 01 00 02 00 03 00 ..".D.f.U.......
13C0:0010 88 00 04 00 33 00 77 00-99 00 12 00 13 00 CC 00 ....3.w.........
13C0:0020 FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
-G 30
AX=0099 BX=0002 CX=0000 DX=0000 SP=FFFC BP=0000 SI=0000 DI=0000
DS=13C0 ES=13B0 SS=13C0 CS=13C4 IP=0030 NV UP EI PL ZR NA PE NC
13C4:0030 CB RETF
-D DS:0
13C0:0000 99 00 88 00 77 00 66 00-55 00 44 00 33 00 22 00 ....w.f.U.D.3.".
13C0:0010 13 00 12 00 11 00 04 00-03 00 02 00 01 00 CC 00 ................
13C0:0020 FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
;有关相对转跳,绝对转跳的解释:
13C6:0000 1E PUSH DS
13C6:0001 2BC0 SUB AX,AX
13C6:0003 50 PUSH AX
13C6:0004 B8C213 MOV AX,13C2
13C6:0007 8ED8 MOV DS,AX
13C6:0009 8B163000 MOV DX,[0030]
13C6:000D 8BCA MOV CX,DX
13C6:000F 4A DEC DX
13C6:0010 8BCA MOV CX,DX
13C6:0012 BB0000 MOV BX,0000
13C6:0015 8B870000 MOV AX,[BX+0000]
13C6:0019 3B870200 CMP AX,[BX+0002]
13C6:001D 7308 JNB 0027 ;在执行JNB指令时,IP已经=001F,执行时1F+08=27F。
13C6:001F 87870200 XCHG AX,[BX+0002]
13C6:0023 89870000 MOV [BX+0000],AX
13C6:0027 83C302 ADD BX,+02
13C6:002A 49 DEC CX
13C6:002B 75E8 JNZ 0015 ;在执行JNZ指令时,IP已经=002D,执行时2D+E8=15H。
13C6:002D 4A DEC DX
13C6:002E 75E0 JNZ 0010 ;在执行JNZ指令时,IP已经=0030,执行时30+E0=10H 。
13C6:0030 CB RETF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -