Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly MASM排序错误_Assembly_Masm_Irvine32 - Fatal编程技术网

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
如能向正确的方向推进,将不胜感激。

尝试失败;-)除其他外:

  • 外部循环以
    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)
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