X86 使用指针增量和索引寻址模式在插入排序中跟踪两个不同的数组索引?
为了自学循环和条件,我尝试从以下方面实现插入排序算法: 非常感谢您的帮助,我的级别是x86的初学者,所以欢迎提供任何提示X86 使用指针增量和索引寻址模式在插入排序中跟踪两个不同的数组索引?,x86,masm,insertion-sort,X86,Masm,Insertion Sort,为了自学循环和条件,我尝试从以下方面实现插入排序算法: 非常感谢您的帮助,我的级别是x86的初学者,所以欢迎提供任何提示 这就是我感到困惑的地方:高级语言假设数组从0开始,然后继续。然而A[j]!=[esi]由于j可能不是=0,因此,我完全陷入了基于索引的寻址部分 您试图将esi用作A+i和ebx用作j似乎在给自己制造麻烦 使用三个不同的寄存器(总共为A、i和j)是一件容易的事情,而不是试图将A+i优化为一个寄存器。 因此A[i]是[esi+edi*4],A[j]是[esi+ebx*4] 这将
这就是我感到困惑的地方:高级语言假设数组从0开始,然后继续。然而
A[j]!=[esi]
由于j
可能不是=0,因此,我完全陷入了基于索引的寻址部分 您试图将esi
用作A+i
和ebx
用作j
似乎在给自己制造麻烦
使用三个不同的寄存器(总共为A
、i
和j
)是一件容易的事情,而不是试图将A+i
优化为一个寄存器。
因此A[i]
是[esi+edi*4]
,A[j]
是[esi+ebx*4]
这将是伪代码到asm的直接翻译
一旦你开始工作,你可以在以后做一些优化,比如把
A+i
和A+j
优化到寄存器中,这样你就可以使用[reg]
寻址模式而不是[reg+idx*4]
寻址模式
您可能根本无法将A
保存在寄存器中,而只能将其用作j>0
的内存源操作数,而不是执行cmp-edx、OFFSET-arr
或cmp-edx、[esp+0]
,如果您假装基址不是编译时常量并将其推送到堆栈上
然后j=i
变成mov-edx,esi
您可能希望将伪代码转换为C,并查看优化编译器的功能。(编写一个将指针作为函数arg的排序函数,这样编译器就不能对常量数组进行常量传播,而只能发出存储常量排序结果的代码:P)这很方便,另请参见。
sbb esi,4
没有意义。如果设置了CF,则不希望减去额外的1。你的意思可能是sub
,而不是用借来减去?还有,为什么要修改数组基以及使用索引寻址模式?@PeterCordes我的意思是SUB
sorry。这就是我感到困惑的地方。高级语言假定数组从0开始并继续。但是A[j]!=[esi]由于j可能不等于0,因此,我完全陷入了基于索引的寻址部分。哇,非常感谢,我已经扭转了我以前所有的尝试,因为我真的很想学习反向工程,因此是x86自学。@Jeet.Deir:我更新了你的问题,使之更具体,并准确地解释了你陷入困境的地方(因此更适合堆栈溢出)。如果此答案完全回答了您的问题,您可以通过单击复选标记“接受”它,让所有人都知道它已解决。问题编辑是谨慎的!只需检查答案!再次感谢!
i ← 1
while i < length(A)
j ← i
while j > 0 and A[j-1] > A[j]
swap A[j] and A[j-1]
j ← j - 1
end while
i ← i + 1
end while
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
.data
arr DWORD 4,5,1,7
.code
main proc
mov esi, OFFSET arr
mov eax, 1 ; eax is i, i <- 1
L2:
mov ebx, eax ; ebx is j, j <- i
; while j > 0
INNERWHILE:
cmp ebx, 0
jle L3
; and A[j-1] > A[j]
mov ecx, [esi + 4*ebx] ; A[j]
sub esi, 4
cmp [esi + 4*ebx], ecx ;A[j-1] > A[j]
jle L3
; swap A[j] and A[j-1]
mov edx, [esi + 4*ebx] ; edx = A[j-1]
add esi, 4
mov ecx, [esi + 4*ebx] ; ecx = A[j]
; Begin Swap
mov [esi + 4*ebx], edx ; A[j-1] <- A[j]
sub esi, 4
mov [esi + 4*ebx], ecx ; A[j] <- A[j-1]
dec ebx
jmp INNERWHILE
L3:
inc eax
cmp eax, LENGTHOF arr
jl L2
invoke ExitProcess,0
main ENDP
END main