下面的流程图用于对从地址[200h]开始的长度为N = 100h的数组进行升序排序,遵循以下原则:
原理:
对数组中的每对连续值进行排序(如果它们没有按升序排序,则交换它们)。
对于副计数器DX的每个值,[SI]和[SI+1]指向要排序的值。由于数组有 N 个值,并且第一遍是比较倒数第二个值和最后一个值,因此主计数器 CX 将必须遍历 (N - 1) 个值,即 CX = N - 1, N - 2, ..., 2, 1。当观察到在辅助计数器 DX 一次遍历其所有相关值之后数组已经排序时,甚至在达到主计数器的限制之前,此解决方案允许停止进程( CX = 1).
对于每个通道 (i)(意味着主计数器 CX = N - i 的每个值),SI 从其初始值 (200h) 变化到值 (200h + N - i - 1),给出 (N - i )值。因此,计数器 DX 将取以下 (N - i) 个值:
这翻译为:
DX = N - i, N - i - 1, N - i - 2, ..., 2, 1
DX = CX, CX - 1, CX - 2, ..., 2, 1
流程图:
start
cx=n-1
etq:
dx=cx
si=200h
bl=0
al=[si]
bcl:
al<=[si+1]
if yes:
si=si+1
dx=dx-1
if no:
permute al,[si+1]
si=al
bl=bl+1
si=si+1
dx=dx-1
zf=1 ?
if yes:
bl=0?
if yes:
end
if no:
cx=cx-1
z=1?
if yes:
end
if no:
etq
if no:
bcl
我尝试将其翻译为下面的代码:
; multi-segment executable file template.
data segment
tab db 30h,35h,23h,37h,38h,39h,31h
n dw 7
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
sub n,1
mov cx,n
etq:
mov dx,cx
mov si,200h
mov bl,0
mov al,[si]
bcl:
cmp al,[si+1]
jbe con
mov dl,al
mov al,[si+1]
mov [si+1],dl
mov si,ax
inc bl
con:
inc si
dec dx
jnz bcl
cmp bl,0
je fin
dec cx
jnz bcl
fin:
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler.
但这并没有改变任何事情。
在流程图伪代码中,
si=al
是错误的,si
是指针,而al
是字符——所以这是类型不匹配和逻辑错误。这转化为一个非常有问题的mov si,ax
。
从损坏的伪代码开始使得编写汇编代码变得非常困难。
您还对第一个
if yes:
进行了有效的优化,消除了它并将 then 部分移至 if no:
(又名 else)部分之后。这是一个很好的优化,尽管我会首先在伪代码中而不是在转录为汇编代码期间进行这样的优化。
我也希望我的伪代码是 C 语言,这样我就可以实际运行它并测试它,特别是在进行这样的优化之后。
此外,伪代码在一处使用
zf=1?
,在另一处使用 z=1?
。这是我喜欢使用 C 来编写伪代码的另一个原因,你可以编译它并查找拼写错误之类的。