【问题标题】:Sort Array (Smallest->Largest) (NASM - Beginner)排序数组(最小->最大)(NASM - 初学者)
【发布时间】:2021-06-13 10:42:23
【问题描述】:

大家好,我是 NASM 的完全新人,我之前在这方面做过大约 5 个项目,而这个是我最复杂的一个。我正在尝试完成从最低值到最高值的数组排序。目前我遇到了一些问题。 我目前正在向某人学习,所以在展示代码之前我会解释一些自定义内容:

我正在使用为每个文件提供的模板,因此会有一些未使用的说明。特别是“代码从这里开始”和“代码从这里结束”上方的那些

call read_int 从终端获取输入并将值放入 eax。

调用 print_int 将 eax 的值打印到终端中。

调用 print_char 将 al 的值打印到终端中。

代码的当前问题

我认为这段代码不起作用的主要问题是我处理最小值索引和当前值之间比较的方式。

目前正在发生的事情

示例输入

1 2 3 4 5 6 7 8 9 10

示例输出

1 1 1 1 1 1 1 1 1 1 

示例输入

235 5476 567 124 6543 75 214 6754 865 143

示例输出

75 124 124 235 235 235 999999999 999999999 999999999 999999999

目的是什么

示例输入:1 2 3 4 5 6 7 8 9 10
示例输出:1 2 3 4 5 6 7 8 9 10

示例输入

235 5476 567 124 6543 75 214 6754 865 143

示例输出

75 124 143 214 235 567 865 5476 6543 6754

解释说明

edi 的起始值设置为较大的数字,以便第一次比较时较小。

indexSmall 的值都设置为 -1 以避免第一次比较时出现最小的索引行

我的压痕可能很糟糕,但这种方法可以帮助我的大脑更好地弄清楚发生了什么。

当我完成此操作后,我将清理一些标签和其他变量名,所以不要拉扯你的头发! :)

任何帮助都会很棒,我已经坚持了一段时间。

编辑:为了澄清,我请求帮助以正确设置此排序算法的索引检查。我相信它没有正确设置,并且在当前使用时给我垃圾信息作为输出。这是该程序的当前设置:

第 1 步获取用户输入。

第 2 步找到最小值。

步骤 3 检查最小值的索引是否与数组 indexSmall 中的索引匹配。如果是,请跳过该值。如果它没有将该值推送到标签 Smaller。

第 4 步 标签 Smaller 将检查该值是否小于当前存储的最小值。 edi用于存储当前循环中的最小值。

第 5 步 EndSearch 将我所有的变量和信息存储到正确的数组中。 EndSearch 循环 10 次遍历整个数组。

第 6 步通过遍历 sortedArray 打印每个变量,每个变量之间有一个空格。

我认为当前设置的问题是索引检查的实施,但我可能是错的。我希望有人可以帮助澄清我的程序可能出了什么问题。谢谢!

%include "/usr/local/share/csc314/asm_io.inc"

segment .data

    sortedArray DD 0,0,0,0,0,0,0,0,0,0
    inputArray DD 0,0,0,0,0,0,0,0,0,0,
    indexSmall DD -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
    arrayCount DD 11
    counter DD 0
    indexHolder DD 0
    

segment .bss

segment .text
    global  asm_main

asm_main:
    push    ebp
    mov     ebp, esp
    ; ********** CODE STARTS HERE **********

    mov edx, 0
    ReadInt:
        call read_int
        mov DWORD [inputArray + edx * 4], eax
        add edx, 1
        CMP edx, 10
        JE EndReadInt
        JMP ReadInt
    EndReadInt:

    mov esi, 0
    Start:
        mov edx, -1
        mov ecx, 0
        mov edi, 999999999
        FindSmallest:
            add edx, 1
            add ecx, 1
            CMP ecx, DWORD [arrayCount]
            JGE EndSearch
            mov eax, DWORD [inputArray + edx * 4]
            mov ebx, DWORD [inputArray + ecx * 4]
            CMP edx, DWORD [indexSmall + esi*4]
            JE Skip
            JMP NoSkip
            Skip:
                JMP FindSmallest
            NoSkip:
                CMP eax, ebx
                JLE Smaller
                JMP FindSmallest
            Smaller:
                CMP eax, edi
                JLE Smallest
                JMP FindSmallest
                Smallest:
                    mov edi, eax
                    sub DWORD [arrayCount], 1
                    mov DWORD [indexHolder], edx
                    JMP FindSmallest
    EndSearch:
        mov eax, DWORD [counter]
        mov DWORD [sortedArray +  eax* 4], edi
        mov eax, DWORD [indexHolder]
        mov DWORD [indexSmall + esi*4], eax
        add esi, 1
        add DWORD [counter], 1
        mov eax, DWORD [counter]
        CMP eax, 10
        JE End
        JMP Start
    End:

    mov edx, 0
    mov al, ' '
    PrintInt:
        mov eax, DWORD [sortedArray + edx*4]
        call print_int
        mov al, ' '
        call print_char
        add edx, 1
        CMP edx, 10
        JE EndPrintInt
        JMP PrintInt
    EndPrintInt:

        

    ; *********** CODE ENDS HERE ***********
    mov     eax, 0
    mov     esp, ebp
    pop     ebp
    ret

编辑 2: asm.io 的内容

    extern  read_int, print_int, print_string
    extern  read_char, print_char, print_nl
    extern  sub_dump_regs, sub_dump_mem, sub_dump_math, sub_dump_stack

%macro  dump_regs 1
    push      dword %1
    call      sub_dump_regs
%endmacro


;
; usage: dump_mem label, start-address, # paragraphs
%macro  dump_mem 3
    push     dword %1
    push     dword %2
    push     dword %3
    call     sub_dump_mem
%endmacro

%macro  dump_math 1
    push     dword %1
    call     sub_dump_math
%endmacro

%macro  dump_stack 3
    push     dword %3
        push     dword %2
    push     dword %1
        call     sub_dump_stack
%endmacro

【问题讨论】:

  • 感谢您对您的情况的可靠解释。但是,我在您的帖子中没有看到任何问题。您想回答的具体问题是什么?
  • 嗨,我在帖子中添加了一个编辑,我认为应该澄清我需要什么。
  • 顺便说一下@Beginner2Everything 我个人不会在代码中放太多缩进。标签实际上并不包含任何代码块,它们只是标记内存中可以跳转或调用的某个地址。使用缩进使标签看起来不像它们。
  • 您是否尝试过使用调试器单步执行代码?这可能会说明错误值的来源以及原因。
  • 如果你能把它设为minimal reproducible example 那就太好了,它包含人们将代码构建到程序中并运行它所需的一切。通过在调试器下运行程序来查找错误比盯着代码并试图在脑海中逐步完成它要容易得多。投入一些精力,让人们更容易为您提供帮助。

标签: sorting assembly nasm


【解决方案1】:

解决了。

下面是一个 10 位数组从小到大排序的代码。

x86 NASM

使用 SASM 进行调试。

感谢大家的帮助。非常推荐安装一些调试器并运行代码。通常我不是那种使用调试器的人,但这个真的很有帮助!


segment .data

ints DD 61,61,75,14,11,77,100,9,39,39
counts DD 1000

segment .bss

segment .text

global _main
_main:
    mov ebp, esp; for correct debugging
    push    ebp
    mov     ebp, esp
    ; ********** CODE STARTS HERE **********

    mov eax, 9
    mov ebx, 8
    MinFinder:
    sub DWORD [counts], 1
    CMP DWORD [counts], 0
    JE Print
    CMP ebx, -1
    JE EndRead
    mov ecx, [ints + eax*4]
    mov edx, [ints + ebx*4]
    CMP ecx, edx
    JL LessThan
    sub eax, 1
    sub ebx, 1
    JMP MinFinder

    LessThan:
    mov [ints + eax*4], edx
    mov [ints + ebx*4], ecx
    sub eax, 1
    sub ebx, 1
    JMP MinFinder

    ; *********** CODE ENDS HERE ***********
    mov     eax, 0
    mov     esp, ebp
    pop     ebp
    ret

【讨论】:

  • 通常一个好的 SO 答案包括用文字描述出了什么问题,或者至少显示了哪些代码行必须更改。否则,对于可能有类似问题的任何人来说,它基本上没有未来价值。 (很高兴您能够调试自己的问题,这对您有好处,但 SO 的主要目的是创建一个有用的 Q&A 存储库。这看起来像 BubbleSort,我们已经有很多可用的 BubbleSort 示例。)跨度>
  • 顺便说一句,您可以简化一些:您不需要两个索引 reg;使用[ints + eax*4 - 4] 之类的寻址模式执行下一个元素偏移。而且您不需要将counts 保留在内存中;循环底部的dec ebx / jnz MinFinder 将起作用。请注意,sub ..., 1 设置了 FLAGS,因此您可以在此基础上进行分支,而无需进行比较。
  • 此外,EBX 是大多数调用约定中的调用保留寄存器,因此您的 _main 应该使用 push/pop 保存/恢复它。此外,1000counts 的初始值比必要的传递次数多方式。或者等一下,你只需要 一个 传球,就可以将 min 降到底部,然后在 ebx < 0 上跳伞。所以counts 基本上是无关紧要的,这不是一个完整的排序,只是冒泡排序的一个内循环传递。如果您只想要最小值,则根本不需要修改数组,除非出于某种原因,运行一次冒泡排序的内循环很有用?
猜你喜欢
  • 2015-12-31
  • 2017-04-16
  • 1970-01-01
  • 2021-11-10
  • 2011-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多