assembly 我如何将一个简单的程序乘以两个数字在玛丽汇编和重写它的语言可读的一个地址的虚拟机

ogsagwnx  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(113)

我的任务是用C语言为VM编写代码。它可以读入文件并根据文件输入执行操作。从我所给出的例子中,似乎每条指令的第一个数字与命令(1 - load,2 - add,3 - store等)有关,第二个数字是地址位置。
到目前为止,我对玛丽和我编写的程序感到很满意,例如,下面的代码用于将2个数字相乘。它还检查输入的数字是否大于0。这很重要

negloop1, clear 
store a 
input 
store a
skipcond 800
jump negloop1 
load a 
output

negloop2, clear 
store b 
input 
store b 
skipcond 800
jump negloop2 
output

load result 
clear 
store result 
load result
add a 
store result 
load b 
subt one 
store b 
skipcond 400
jump 012 
load result 
output 
halt

a,            dec 0
b,            dec 0
one,        dec 1
result,     dec 0

字符串
我需要写一个程序,用一种语言做同样的事情,这种语言可以被一个用c语言写的微型虚拟机读懂。它具有由数字1 - 11中的操作码表示的以下指令(加载、添加、存储、子、输入、输出、停止、jmp、skipz、skipg、skipl)。所以指令应该是这样的。

5 5 //in 5
6 7 // out 7
3 0 // store 0
7 0 // halt


我不知道我该如何把我的程序翻译成这种类型的指令。我需要实现跳转命令,但无法引用要跳转到的行。另外,似乎没有一个与“clear”等效的命令。

xienkqul

xienkqul1#

首先,从逻辑上讲,一些最有用和最复杂的运算是二元运算符,它们是三个操作数,在某种意义上它们使用两个源和一个目的地;它们像加法一样有用,并且由于所需的操作数的数量而复杂。
像玛丽这样的单操作数机器几乎肯定有累加器。它可以指定其中一个源,然后将累加器用于第二个源操作数,也可以用于目的操作数以捕获结果.(正如@Peter所指出的,一个操作数机器也可以是一个堆栈机器。)
玛丽已经是这样一台机器:我们来看看二元运算符是如何执行的,在玛丽中,它们是addsubt-这些指令指定一个(源)内存操作数,另一个源操作数用作累加器,而结果则被捕获回累加器。
玛丽也有“一元”操作,即加载和存储,提供一个内存操作数(分别作为源或目标),也与累加器一起工作。
我不知道我该如何将我的程序翻译成这种类型的指令。
当我们将C代码转换为程序集,或者将一个程序集转换为另一个程序集时,需要确定三种逻辑构造来进行转换:

  • 变数
  • 表示式
  • 报表

首先,我建议您将注意力集中在如下代码序列上:

load result
add a 
store result

字符串
对于上述内容,您需要将aresultMap到存储,这涉及到变量的转换。因此,例如,您可以选择将a放入位置0,(将b放入位置1),并将result放入位置2。
(We我不能告诉您这些位置是否可以免费使用,但由于您指定了哈佛Architecture,因此我们假定您可以使用从0开始的数据位置。)
接下来,您将需要使用已经完成的变量Map来翻译执行完整加法赋值语句的指令。比如说:
| 已Map的变量|您的虚拟机| Your VM |
| --|--| ------------ |
| 负载2| 1个2个| 1 2 |
| 添加0|二0| 2 0 |
| 商店2| 3个2| 3 2 |
最后,由于这是一个简单的赋值语句,因此通常将它放在与其他代码相对的位置,就像它在玛丽程序集中一样。
循环要求您更仔细地查看控制流构造,但玛丽已经具有反映在VM中的相对原始的控制结构。

multiply, load result
add a 
store result 
load b 
subt one 
store b 
skipcond 400
jump multiply


此循环执行以下操作(在C语言中):

do {
    result += a;
 } while (--b != 0);


目的是重复加法,直到b(向下计数)变为零。转换到您的虚拟机应该很简单。
由于玛丽代码使用SkipCond 400,它在零上跳过-而被跳过的是jump,那么从语义上讲,它意味着在非零上的jump
但是,由于玛丽使用的汇编程序带有我认为您没有的标签,因此您需要为jump指令的操作数提供一个计数或值,而不是标签。对于jump的操作数有两种基本的体系结构选择,一种是绝对地址(这是玛丽所做的),另一种是pc相对偏移量(大多数其他机器都会做)。一旦您决定了操作数的含义(操作数如何标识目标),那么您就需要一个编码(即如果是相对于PC,则如何对反向分支的负数进行编码)。
您可以稍微考虑一下您希望in(和out)执行的操作。玛丽对此不接受操作数;它使用累加器作为目标input和源output。当然,您可以让in & out使用操作数来代替,因此在玛丽中我们可以说两条指令:in; store a,则只有一条指令,即in a,或5个0。

相关问题