我正在使用MASM和Irvine的图书馆进行作业。在程序的这一步中,我正在尝试对接收到的数组进行排序,但是我在实现时遇到了问题。
ordr_array PROC
pushad
mov ebp, esp
mov edx, [ebp+40] ; array value
mov ebx, 0 ; array position
; [ebp+36] ; length of input_n
mov eax, [ebp+36]
; counts up to ecx
mov eax, 0
looper:
inc eax ; k++
mov ecx, eax
inc ecx ; j = k + 1
inner_looper:
push eax ; we need these registers,
push ecx ; save them
mov eax, [edx+4*eax] ; move our values into our registers for comparison
mov ecx, [edx+4*ecx]
cmp eax, ecx
jge inner_looper_end
mark: ; array[j] > array[i]
mov ebx, ecx ; put the inner counter value (j) to swap with the outer (i)
inner_looper_end:
pop ecx ; restore registers
pop eax ; ecx and eax
inc ecx
cmp ecx, [ebp+36]
jl inner_looper ; if we're done with the inner loop, just fall out
looper_end: ; finish looper
; exchange code
push [edx+4*eax]
push [edx+4*ecx]
call exchangeElements
; end exchange code
; see if we need to go again
inc eax
inc eax ; the '+ 1' then '- 1' was the best way I could think of doing '< result - 1' from memory
cmp eax, [ebp+36]
dec eax
jl looper
popad
ret 8
ordr_array ENDP
调用的交换函数是:
exchangeElements PROC
pushad
mov eax, [ebp+36] ;to be swapped
mov ebx, [ebp+40] ;to be swapped
push [eax]
push [ebx]
pop [eax] ;this should swap it
pop [ebx] ;this should swap it
popad
ret 8
exchangeElements ENDP
非常感谢正确方向的推动。
答案 0 :(得分:0)
尝试失败;-)除其他外:
inc eax
开始外部循环,这意味着您以EAX = 1开始。EAX
和ECX
用作元素的索引和值,并感到困惑。exchangeElements
会获得相当随机的值,但需要元素的地址和后面的最小值的地址。我建议先以一种高级编程语言解决该问题,直到算法生效。我想你想编写这样的东西:
PHP-CLI
<?php
$A = "Jacobm001";
$A = str_split ($A, 1);
$L = count($A);
ordr_array ($A,$L);
printf("%s\n",print_r($A,true));
function ordr_array (&$A, $L)
{
for ($i = 0; $i < ($L-1); ++$i)
{ $B = $A[$i]; $bb = $i;
for ($j = ($i+1); $j < $L; ++$j)
{
if ($A[$j] < $B)
{
$B = $A[$j];
$bb = $j;
}
}
exchangeElements ($A[$i],$A[$bb]);
}
}
function exchangeElements (&$A, &$B)
{
$T = $A;
$A = $B;
$B = $T;
}
?>
Python
def ordr_array (A, L):
# outer loop
for i in range (0,L-1):
B = A[i]
bb = i
# inner loop
for j in range (i+1, L):
if (A[j] < B):
B = A[j]
bb = j
# exchangeElements
A[i], A[bb] = A[bb], A[i]
A = ['J','a','c','o','b','m','0','0','1']
L = len (A)
ordr_array (A,L)
print (A)
C99
#include <stdio.h>
#include <string.h>
void exchangeElements (char* A, char* B)
{
char T = *A;
*A = *B;
*B = T;
}
void ordr_array (char A[], size_t L)
{
for (size_t i = 0; i < (L-1); i++)
{
char B = A[i];
size_t bb = i;
for (size_t j = i+1; j < L; j++)
{
if (A[j] < B)
{
B = A[j];
bb = j;
}
}
exchangeElements (&A[i], &A[bb]);
}
}
int main ( void )
{
char A[] = "Jacobm001";
size_t L = strlen (A);
ordr_array (A, L);
printf ("%s\n",A);
return 0;
}
很高兴我在您的个人资料中没有找到Haskell或Brainfuck:-)
如果该算法有效,则可以在汇编器中逐点转换。最好的是,您采用了C程序。恶意语言说C是高级汇编语言。不要忽略所使用的汇编器和库的功能。
MASM和IRVINE32
INCLUDE Irvine32.inc
.DATA
arr DD 'J','a','c','o','b','m','0','0','1'
.CODE
main PROC
push LENGTHOF arr ; https://docs.microsoft.com/en-us/cpp/assembler/masm/operator-lengthof
push OFFSET arr ; https://docs.microsoft.com/en-us/cpp/assembler/masm/operator-offset?
call ordr_array
mov ecx, LENGTHOF arr
lea esi, arr
@@:
lodsd
call WriteChar ; Irvine: Writes a single character in AL to standard output
loop @B
mov al, 0Dh ; New Line
call WriteChar
exit
main ENDP
ordr_array PROC STDCALL, A:PTR, L:DWORD ; STDCALL & arguments forces MASM to produce `RET x`
LOCAL bb:DWORD
pushad ; PUSHAD is elegant, but not effective ;-)
mov edx, A ; Address of array
dec L ; Convert length of array to number of last index
xor eax, eax
.WHILE (eax < L) ; https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-while
mov esi, [edx+4*eax]
mov ebx, esi
mov ecx, eax
mov bb, ecx
.WHILE (ecx < L) ; Inner loop
inc ecx
mov edi, [edx+4*ecx]
.IF (edi < esi && edi < ebx) ; Looking for the minimum
mov ebx, edi ; Save value of minimum
mov bb, ecx ; Save index of minimum
.ENDIF
.ENDW ; End of inner loop
mov ecx, bb
lea ecx, [edx+4*ecx] ; B = Address of minimum
push ecx
lea ecx, [edx+4*eax] ; A = Address of outer loop element
push ecx
call exchangeElements
; mov ecx, bb ; exchangeElements inline
; mov [edx+4*eax], ebx
; mov [edx+4*ecx], esi
inc eax
.ENDW ; End of outer loop
popad
ret ; = `ret 8` due to STDCALL & arguments
ordr_array ENDP
exchangeElements PROC STDCALL USES eax ecx esi edi, A:PTR, B:PTR
mov esi, A
mov edi, B
mov eax, [esi]
mov ecx, [edi]
mov [esi], ecx
mov [edi], eax
ret ; = `ret 8` due to STDCALL & arguments
exchangeElements ENDP
END main