初学汇编,被各种指令折磨得不浅。由于汇编得底层性,涉及到很多细节的东西,且一条指令只能实现一个动作,就显得很繁杂。
今天写了个选择排序来熟悉熟悉这门语言。思考过程如下:
;确认目标:将以BUFFER为首地址的字节数组按照从大到小的顺序排序(选择排序)
;分析过程:
;1.用到2重循环,外层循环通过内层循环找到的第DI大的数的下标BX,交换BUFFER[DI]和BUFFER[BX]。需要初始化AL和DI,LEN,SI,CX
;2.内层循环,从BUFFER[DI]开始往后找,找到最大的数,传到AL中,同时记录对应的最大值的下标到BX中。初始化CX做计数器,SI做下标,BX存最大值的下标
最后排好序的结果存在了BUFFER里面,属于原地排序。结果可以在variable查看
;代码实现:
DATA SEGMENT
BUFFER DB 9,4,8,3,8,2,6,1
LEN EQU $ - BUFFER
DATA ENDS
CODE SEGMENT
ASSUME CS : CODE, DS : DATA
START:
MOV AX, DATA
MOV DS, AX
INIT:
MOV DI, -1;再外层循环会先对DI实行+1的操作,所以这里要设成-1,使第一次循环找的是第0大的数(也就是最大值)
MOV AL, 0;存着每一次内循环的最大值
OUT:
INC DI
MOV CX, LEN
SUB CX, DI
MOV SI, DI
DEC SI;指着要比较的前一位即DI-1,因为内层循环需要先对SI+1
MOV BX, DI;BX存的是每一次内循环最大值的下标
MOV AL, 0
CMP DI, LEN - 1
JC IN;DI小于数组的最后一位的下标就继续循环
JMP EXIT
IN:
INC SI
DEC CX
CMP CX, 0;CX<0就进入下标赋值阶段,也就是C语言实现选择排序时外层for循环的最后一句即介于内层循环外和外层循环内的那一句。再通过赋值跳转回外循环,汇编每出一个循环都要判断跳转一下
JL FUZHI;这里要把CX看成有符号数,因为CX的结束条件是=-1
CMP AL, BUFFER[SI]
JAE IN;AL大或等于BUFFER[SI]的话就下一次循环,可是AL如果直接是最大,就会陷入死循环,应该在前面添加一个对CX的判断
MOV AL, BUFFER[SI] ;这里记得更新AL
MOV BX, SI;AL是小的值得情况,把大得值得下标赋给BX
JMP IN
FUZHI:
;交换BUFFER[DI]和BUFFER[BX]
MOV DL, BUFFER[DI]
XCHG DL, BUFFER[BX]
MOV BUFFER[DI], DL
JMP OUT
EXIT:
MOV AX, 4C00H
INT 21H
CODE ENDS
END START