【发布时间】: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 那就太好了,它包含人们将代码构建到程序中并运行它所需的一切。通过在调试器下运行程序来查找错误比盯着代码并试图在脑海中逐步完成它要容易得多。投入一些精力,让人们更容易为您提供帮助。