gpt4 book ai didi

通过平面 assembly 中的过程对列表进行排序

转载 作者:行者123 更新时间:2023-12-04 08:24:47 25 4
gpt4 key购买 nike

我对 fasm 很陌生,我最近才开始学习程序。我的问题是我有一个 proc,我希望它以某种方式对我的列表进行排序。但是当我运行我的代码时,它似乎只是从内存中对一些随机数进行排序。我不太清楚为什么会发生这种情况,我将不胜感激。
这是代码:

format PE gui 5.0
include 'D:\Flat Assembler\INCLUDE\win32a.inc'
entry start

section '.data' data readable writable
mas1 dw 2, -3, 1, -1, 3, -2, 5, -5, -4, 4

N = ($ - mas1) / 2
numStr db N dup('%d '), 0

strStr db '%s', 0
undefStr db 'undefined', 0
buff db 50 dup(?)
Caption db 'Result', 0


section '.code' code readable executable
start:

stdcall bubble, mas1

cinvoke wsprintf, buff, numStr
invoke MessageBox, 0, buff, Caption, MB_OK + MB_ICONINFORMATION
invoke ExitProcess, 0


proc bubble, mas:word
mov ecx, 0
mov ebx, 0

outerLoop:
cmp ecx, 10
je done
mov ebx, 2

innerLoop:
mov eax, 0
mov edx, 0

cmp [mas+ebx], 0 ;if(mas[j] > 0)
jge continue ;continue

mov ax, [mas+ebx-2]

cmp ax, [mas+ebx]
jle continue
mov dx, [mas+ebx]
mov [mas+ebx-2], dx
mov [mas+ebx], ax

continue:
cmp ebx, 18 ;10
je innerDone
add ebx, 2 ;inc ebx
jmp innerLoop

innerDone:
inc ecx
jmp outerLoop

done:
mov ecx, 0
mov ebx, 0
mov ebx, 18
mov ecx, N
print:
mov eax, 0
mov ax, [mas+ebx]
cwde
push eax
sub ebx, 2
loop print

ret
endp

section '.idata' import data readable writeable
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL'

include 'D:\Flat Assembler\INCLUDE\API\kernel32.inc'
include 'D:\Flat Assembler\INCLUDE\API\user32.inc'

最佳答案

错误 1

stdcall bubble, mas1
...
proc bubble, mas:word

参数 mas1 是一个地址,并作为双字压入堆栈。因此,您不应将参数 mas 限制为一个词。
你的冒泡过程需要的是数组的完整地址。您可以通过 mov esi, [mas] 获得此信息FASM 会像你写的那样编码 mov esi, [ebp+8] . EBP+8当标准序言 push ebp 时,第一个参数(并且在您的程序中是唯一的参数)所在的位置。 mov ebp, esp用来。
错误 2
在您的冒泡过程中,您将结果数组插入堆栈,希望得到 wsprintf从那里使用它,但是一旦冒泡过程执行其 ret指令、结尾代码以及 ret指令本身将开始吃掉你的数组 甚至返回内存中的错误地址 !
如果要通过堆栈返回数组,请将其存储在返回地址和参数上方。这就是为什么我在下面的程序中写道:
sub esp, N*4                  ; Space for N dwords on the stack
stdcall bubble, mas1
错误 3
cmp [mas+ebx], 0 ;if(mas[j] > 0)
jge continue ;continue

您的 BubbleSort 是错误的,因为您不允许比较正数!
此外,您进行了太多的迭代,这些迭代也持续了太长时间。

我在 FASM 1.71.22 上测试了以下程序 不要忘记更改路径!
format PE gui 5.0
include 'C:\FASM\INCLUDE\win32a.inc'
entry start

section '.data' data readable writable
mas1 dw 2, -3, 1, -1, 3, -2, 5, -5, -4, 4
N = ($ - mas1) / 2

numStr db N-1 dup('%d, '), '%d', 0
;strStr db '%s', 0
;undefStr db 'undefined', 0
buff db 50 dup(?)
Caption db 'Result', 0


section '.code' code readable executable
start:

sub esp, N*4 ; Space for N dwords on the stack
stdcall bubble, mas1

cinvoke wsprintf, buff, numStr
invoke MessageBox, 0, buff, Caption, MB_OK + MB_ICONINFORMATION
invoke ExitProcess, 0


proc bubble uses ebx esi, mas

mov esi, [mas] ; Address of the array
mov ecx, (N-1)*2 ; Offset to the last item; Max (N-1) compares

outerLoop:
xor ebx, ebx

innerLoop:
mov ax, [esi+ebx]
mov dx, [esi+ebx+2]
cmp ax, dx
jle continue
mov [esi+ebx+2], ax
mov [esi+ebx], dx
continue:
add ebx, 2
cmp ebx, ecx
jb innerLoop

sub ecx, 2
jnz outerLoop

mov ebx, (N-1)*2
toStack:
movsx eax, word [esi+ebx]
mov [ebp+12+ebx*2], eax
sub ebx, 2
jnb toStack

ret
endp

section '.idata' import data readable writeable
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL'

include 'C:\FASM\INCLUDE\API\kernel32.inc'
include 'C:\FASM\INCLUDE\API\user32.inc'

错误 2 重温
如果您的冒泡过程没有修改原始数组,IMO 通过堆栈返回结果数组会更有意义。
但是在您目前的代码中,您这样做了,所以......
一旦你从冒泡过程中提取 toStack 片段,你可以简单地(从冒泡过程返回后)将数组的字大小的元素作为双字推送到堆栈,然后使用 wsprintf .
  ...

start:
stdcall bubble, mas1
mov ebx, (N-1)*2
toStack:
movsx eax, word [mas1+ebx]
push eax
sub ebx, 2
jnb toStack
cinvoke wsprintf, buff, numStr

...

sub ecx, 2
jnz outerLoop
; See no more toStack here!
ret
endp

...

关于通过平面 assembly 中的过程对列表进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65321353/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com