首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MASM排序错误

MASM排序错误
EN

Stack Overflow用户
提问于 2013-11-25 13:22:09
回答 1查看 156关注 0票数 0

我正在使用MASM和欧文的库做一项任务。在程序的这一步中,我试图对接收到的数组进行排序,但在实现时遇到了问题。

代码语言:javascript
运行
复制
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

调用的交换函数为:

代码语言:javascript
运行
复制
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

如果能朝着正确的方向推进,我们将非常感激。

EN

回答 1

Stack Overflow用户

发布于 2020-02-08 22:07:04

尝试失败;-)其中包括:

  • 您以inc eax开始外部循环,这意味着您以EAX=1开始。
  • 您将EAXECX作为元素的索引,并将其作为其值,这使您感到困惑。
  • 它看起来像是您弄乱了数组的长度,它的最后一个值相当随机,但需要一个元素的地址和后面最小值的地址。<代码>H212<代码>F213

我建议先用高级编程语言来解决这个问题,直到算法生效为止。我猜你想要编写类似这样的程序:

CLI PHP-

代码语言:javascript
运行
复制
<?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

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20185289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档