因此,我们正在研究我们的教授向我们展示的英特尔8086插入分类代码。他希望我们弄清楚为什么代码跳过数组中的第0个元素和数组中的第3个元素来自他从网上获取的代码。
; void isort(int *a, int n)
; sorts the first n elements of a
;
; Parameters
; a - pointer to the array
; n - number of elements to sorts
%define a [ebp + 8]
%define n [ebp + 12]
isort:
enter 0, 0
pusha
mov ecx, 1
for:
mov ebx, ecx
imul ebx, 4
add ebx, a
mov ebx, [ebx]
mov edx, ecx
dec edx
while:
cmp edx, 0
jl while_quit
mov eax, edx
imul eax, 4
add eax, a
cmp ebx, [eax]
jge while_quit
mov esi, [eax]
mov dword [eax + 4], esi
dec edx
jmp while
while_quit:
mov [eax], ebx
inc ecx
cmp ecx, n
jl for
popa
leave
ret
样本数组是{5,8,12,2,1,7}。这是为了理解8086语言,因为我们刚开始几天,我想知道是否有人可以解释如何以及可能出现的问题。
答案 0 :(得分:0)
考虑ECX
为1时代码将执行的操作:
while
循环将与EBX=8
和EDX=0
一起输入。jl while_quit
将不会被采用,因为EDX
为0。EBX
与[EAX]
进行比较。那是;将8与a[0]
进行比较,即{5},因此jge while_quit
被采用。mov [eax], ebx
在a[0]
存储8个,因此您的数组现在包含{8,8,12,2,1,7}
。显然不是你想要的,因为你丢失了一个原始元素。除了代码的逻辑缺陷之外,那些imul
指令完全没必要,因为你可以在x86上使用缩放索引。因此,排序代码可以简化为此(我已经验证它正确排序了数组):
mov ecx, 1
for_:
; esi = &a[holePos]
lea esi,[a + ecx*4]
; valueToInsert = a[holePos]
mov ebx, [esi]
while_:
; Did we reach the beginning of the array?
cmp esi, OFFSET a
jle while_quit
; valueToInsert < a[holePos-1] ?
cmp ebx, [esi-4]
jge while_quit
; a[holePos] = a[holePos-1]
mov eax, [esi-4]
mov [esi], eax
; esi = &a[holePos-1]
sub esi,4
jmp while_
while_quit:
; a[holePos] = valueToInsert
mov [esi], ebx
inc ecx
cmp ecx, 6
jl for_
我正在使用MASM语法,但你明白了。