我正在尝试解决以下任务:
在 MARIE 中编写汇编代码,将以下数字(十六进制)从最大到最小排序。
数字(十六进制):5、35、75、45、85、25、95、55、15、65
- 您必须按照给定的顺序并以十六进制值的形式将给定值存储在内存中。
- 您必须对值进行排序并将它们存储在存储原始值的同一内存位置中。
- 您的代码不应询问任何输入值。
我尝试使用冒泡排序算法对这些数字从最小到最大进行排序。
这是我的代码:
ORG 1000 // Start of memory allocation
// Define variables
NUMBERS, HEX 5, 35, 75, 45, 85, 25, 95, 55, 15, 65
FLAG, DEC 0
// Constants
One, DEC 1
// Start of the program
Main, Load NUMBERS // Load the first number into AC
Store 2000 // Store it in a temporary location for swapping
Add One // Move to next number
Store X // Store the address of the next number
Loop1, Load X // Load the next number into AC
Skipcond 400 // If end of array is reached, exit the loop
Jump EndLoop1 // Jump to end of outer loop if end of array is reached
Load 2000 // Reload the first number into AC
Subt X // Compare the two numbers
Skipcond 800 // If AC is greater than or equal to X, jump
Jump Swap // Jump to swap the numbers
Jump Loop1 // Continue outer loop
Swap, Load X // Load the next number into AC
Store 3000 // Store it in a temporary location
Load 2000 // Load the first number into AC
Store X // Store it in the location of the next number
Load 3000 // Load the next number from the temporary location
Store 2000 // Store it in the location of the first number
Store FLAG // Set flag indicating a swap was made
Jump Loop1 // Continue outer loop
EndLoop1, Load FLAG // Load flag value
Skipcond 400 // If flag is 0 (no swaps), exit outer loop
Jump Main // Otherwise, repeat outer loop
// End of program
Halt // Halt the program
// Variables and constants allocation
X, DEC 0
我在第 4 行收到错误:
NUMBERS, HEX 5, 35, 75, 45, 85, 25, 95, 55, 15, 65
我检查了我的代码,即使有语法,我也不知道哪里可能有错误。
我使用 MARIE 模拟器在我的 IDE 中运行这些指令,同时还使用在线 MARIE 模拟器,只是为了确保我的 IDE 没有问题。
我遇到的另一个问题是,每当我尝试用代码找出错误时,我的程序集列表选项卡都是完全空白的。它在我的 MARIE 编辑器上显示的唯一一件事是我有一个错误,甚至没有指定该行。
我将范围缩小到尝试创建一个由十六进制组成的数组,即上面代码中的第 4 行。我使用的在线 MARIE 模拟器也突出显示了第 4 行的错误。
我做错了什么?
正如评论中已经提到的,您需要为数组中的每个数字使用一行,所以不要这样:
NUMBERS, HEX 5, 35, 75, 45, 85, 25, 95, 55, 15, 65
这样做:
NUMBERS, HEX 5
HEX 35
HEX 75
HEX 45
HEX 85
HEX 25
HEX 95
HEX 55
HEX 15
HEX 65
其他一些问题:
您写道您想要对值进行排序“从最小到最大”,但请注意,您引用的任务要求相反(“从 最大到最小*")
Store 2000
:在 MARIE.js.org 上,此语句会触发汇编错误:“地址 2000 超出范围。”。您不需要在指令操作数中硬编码地址。相反,在数据部分定义变量,并使用它们的名称。
MARIE.js.org的在线模拟器无法解释
Halt //
。双斜杠让人困惑。请注意,注释应该仅以 one 斜线开头。更换即可解决问题。
将所有数据放在程序后面。目前您已在节目之前传播了一些数据(
NUMBERS
、FLAG
、ONE
),以及在节目之后传播了其他一些数据(X
)。
指令
Add One // Move to next number
并没有按照评论的建议进行操作。累加器具有在数组中找到的值,而不是其地址。所以你并没有在你想要的东西上添加一个。要获取数组的地址,您可以使用 Erik Eidt 在这个答案中解释的指针编码。
一旦修复了上一点,
Load X
就不会加载数组值,而是加载地址。要加载该数组地址处的值,请使用 LoadI X
。与Subt X
同样的问题。在交换算法中,您需要它与 StoreI
结合使用。
您对
Skipcond 400
的解释错误:代码和注释表明您认为当累加器为0时将执行下一条语句,但事实恰恰相反:当累加器为0时,下一条语句将被skipped是这样的。
相关,注释“如果AC大于或等于X,则跳转”是错误的。操作数
Skipcond 800
表示“当 AC 大于零时跳过下一条语句”(不等于!)。
您的代码中没有任何地方可以将标志重置回 0。当您到达
EndLoop1
时,您需要在重复程序之前将标志重置回 0。
您认为数组以零终止,但这是
FLAG
的内存位置,当您在交换时更改其值时,您会破坏该数组结束标记,这将使您的代码读取不属于数组的内容。
这是您的代码的修复:
// Start of the program
Main, Clear / Clear the flag (to indicate that no swap was made so far)
Store Flag
Load NumbersAdr / Load the address of the first number into AC
Store PrevAdr / Store it in a temporary location for swapping
Add One / Move to next number
Store CurrAdr / Store the address of the next number
Loop1, LoadI CurrAdr / Load the next number into AC
Skipcond 400 / If end of array is reached, exit the loop
Jump Continue
Jump EndLoop1 / Jump to end of outer loop if end of array is reached
Continue, Store Curr
LoadI PrevAdr / Compare the two numbers
Subt Curr
Skipcond 800 / If previous value is greater, swap
Jump Step / No swap needed, continue outer loop
Swap, LoadI PrevAdr / Load the lesser number into AC
StoreI CurrAdr
Load Curr
StoreI PrevAdr
Store Flag / Set flag indicating a swap was made
Step, Load CurrAdr
Store PrevAdr
Add One
Store CurrAdr
Jump Loop1 / Continue outer loop
EndLoop1, Load Flag / Load flag value
Skipcond 400 / If flag is 0 (no swaps), exit outer loop
Jump Main
/ End of program
Halt / Halt the program
/ Variables
CurrAdr, DEC 0 / Pointer that traverses the array
PrevAdr, DEC 0 / Pointer that follows one step behind
Curr, DEC 0 / Temporary copy of the current value
Flag, DEC 0 / Flag indicating whether last traversal made a swap
/ Array to sort
Numbers, HEX 5
HEX 35
HEX 75
HEX 45
HEX 85
HEX 25
HEX 95
HEX 55
HEX 15
HEX 65
/ Constants
Terminator, DEC 0 / To mark end of the array (Must be constant!)
One, DEC 1
NumbersAdr, JnS Numbers / Pointer to the start of the array
您可以在 MARIE.js.org 上在线组装并运行它。