Assembly MASM排序错误
我正在用马斯姆和欧文的图书馆做作业。在程序的这一步中,我试图对接收到的数组进行排序,但在实现上遇到了问题Assembly MASM排序错误,assembly,masm,irvine32,Assembly,Masm,Irvine32,我正在用马斯姆和欧文的图书馆做作业。在程序的这一步中,我试图对接收到的数组进行排序,但在实现上遇到了问题 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
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
如能向正确的方向推进,将不胜感激。尝试失败;-)除其他外:
- 外部循环以
开始,这意味着外部循环以eax=1开始inc eax
- 您将
和EAX
作为元素的索引及其值,这样会混淆ECX
- 看起来您正在弄乱数组的长度及其最后一个索引
获取非常随机的值,但需要元素的地址和后面最小值的地址exchangeElements
<?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)
def ordr_数组(A,L):
#外环
对于范围(0,L-1)内的i:
B=A[i]
bb=i
#内环
对于范围(i+1,L)内的j:
如果(A[j]
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;
}
#包括
#包括
无效交换元素(字符*A,字符*B)
{
chart=*A;
*A=*B;
*B=T;
}
void ordr_数组(字符A[],大小\u t L)
{
对于(尺寸i=0;i<(L-1);i++)
{
字符B=A[i];
尺寸_tbb=i;
对于(尺寸j=i+1;j
我很高兴在你的个人资料中没有找到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
包括Irvine32.inc
.数据
arr DD'J','a','c','o','b','m','0','0','1'
.代码
主进程
arr的推送长度;https://docs.microsoft.com/en-us/cpp/assembler/masm/operator-lengthof
推偏arr;https://docs.microsoft.com/en-us/cpp/assembler/masm/operator-offset?
调用ordr\u数组
mov ecx,arr长度
利埃西,阿
@@:
lodsd
呼叫WriteChar;欧文:将AL中的单个字符写入标准输出
循环@B
mov-al,0Dh;新线
呼叫WriteChar
出口
主端
ordr_数组进程STDCALL,A:PTR,L:DWORD;STDCALL和arguments强制MASM生成'RET x`
本地bb:DWORD
普沙德;PUSHAD很优雅,但并不有效;-)
mov-edx,A;数组地址
十二月一日;将数组长度转换为最后一个索引的数目
异或eax,eax
.而(eax
您尚未解释问题所在,但看起来您是在按值将参数传递给swap函数,然后将参数视为函数内的地址。@Michael:调用exchange元素时出错。这只是一条紧急消息,没有什么特别有用的。
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