- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在读书学习The Elements of Computing Systems但我被困在某一时刻。示例章节跳过下5条指令可查here .
无论如何,我正在尝试实现一个虚拟机(或一个字节码到汇编翻译器),但我被困在跳过接下来的 5 条指令。
你可以找到汇编符号here .
目标是实现一个翻译器,将特定的字节码翻译成这个汇编代码。
我成功完成的一个例子是字节码
push constant 5
翻译成:
@5
D=A
@256
M=D
正如我所说,Hack 的汇编语言可以在我提供的链接中找到,但基本上:
@5 // Load constant 5 to Register A
D=A // Assign the value in Reg A to Reg D
@256// Load constant 256 to Register A
M=D // Store the value found in Register D to Memory Location[A]
好吧,这非常简单。根据定义,内存位置 256 是堆栈的顶部。所以
push constant 5
push constant 98
将被翻译成:
@5
D=A
@256
M=D
@98
D=A
@257
M=D
一切都很好..
我还想再举一个例子:
push constant 5
push constant 98
add
翻译成:
@5
D=A
@256
M=D
@98
D=A
@257
M=D
@257 // Here starts the translation for 'add' // Load top of stack to A
D=M // D = M[A]
@256 // Load top of stack to A
A=M // A = M[A]
D=D+A
@256
M=D
我觉得已经很清楚了。
但是我不知道如何翻译字节码
eq
到 assembly 。 eq的定义如下:
Three of the commands (eq, gt, lt) return Boolean values. The VM represents true and false as -1 (minus one, 0xFFFF) and 0 (zero, 0x0000), respectively.
所以我需要将两个值分别弹出到寄存器A和D中,这很容易。但是我应该如何创建一个汇编代码来检查这些值并在结果为真时压入 1 或在结果为假时压入 0?
Hack Computer支持的汇编代码如下:
我可以这样做:
push constant 5
push constant 6
sub
如果压入堆栈的 2 个值相等,它将保存值 0,否则将保存 !0,但这有什么帮助呢?我尝试使用 D&A 或 D&M,但这也没有太大帮助..
我也可以引入条件跳转,但我怎么知道要跳转到哪条指令呢? Hack 汇编代码没有诸如“跳过接下来的 5 条指令”之类的内容。
[由 Spektre 编辑] 我所看到的目标平台摘要
SP(R0),LCL(R1),ARG(R2),This(R3),That(R4)
最佳答案
似乎还有另一章更明确地定义了 Hack CPU。它说:
The Hack CPU consists of the ALU specified in chapter 2 and three registers called data register (D), address register (A), and program counter (PC). D and A are general-purpose 16-bit registers that can be manipulated by arithmetic and logical instructions like A=D-1 , D=D|A , and so on, following the Hack machine language specified in chapter 4. While the D-register is used solely to store data values, the contents of the A-register can be interpreted in three different ways, depending on the instruction’s context: as a data value, as a RAM address, or as a ROM address
显然,“M”访问是由 A 控制的 RAM 位置。这是我遗漏的间接寻址。现在一切正常。
随着混淆的消除,现在我们可以处理 OP 的问题(更容易)。
让我们从使用堆栈实现子程序调用开始。
; subroutine calling sequence
@returnaddress ; sets the A register
D=A
@subroutine
0 ; jmp
returnaddress:
...
subroutine: ; D contains return address
; all parameters must be passed in memory locations, e.g, R1-R15
; ***** subroutine entry code *****
@STK
AM=M+1 ; bump stack pointer; also set A to new SP value
M=D ; write the return address into the stack
; **** subroutine entry code end ***
<do subroutine work using any or all registers>
; **** subroutine exit code ****
@STK
AM=M-1 ; move stack pointer back
A=M ; fetch entry from stack
0; jmp ; jmp to return address
; **** subroutine exit code end ****
“push constant”指令可以很容易地转换为存储到堆栈中的动态位置:
@<constant> ; sets A register
D=A ; save the constant someplace safe
@STK
AM=M+1 ; bump stack pointer; also set A to new SP value
M=D ; write the constant into the stack
如果我们想创建一个子程序来推送常量:
pushR2: ; value to push in R2
@R15 ; save return address in R15
M=D ; we can't really use the stack,...
@R2 ; because we are pushing on it
D=M
@STK
AM=M+1 ; bump stack pointer; also set A to new SP value
M=D ; write the return address into the stack
@R15
A=M
0 ; jmp
并调用“push constant”例程:
@<constant>
D=A
@R2
M=D
@returnaddress ; sets the A register
D=A
@pushR2
0 ; jmp
returnaddress:
推送变量值 X:
@X
D=M
@R2
M=D
@returnaddress ; sets the A register
D=A
@pushR2
0 ; jmp
returnaddress:
从堆栈中弹出一个值到 D 寄存器的子程序:
popD:
@R15 ; save return address in R15
M=D ; we can't really use the stack,...
@STK
AM=M-1 ; decrement stack pointer; also set A to new SP value
D=M ; fetch the popped value
@R15
A=M
0 ; jmp
现在,执行 OP 最初要求的“EQ”计算:
EQ: ; compare values on top of stack, return boolean in D
@R15 ; save return address
M=D
@EQReturn1
D=A
@PopD
0; jmp
@EQReturn1:
@R2
M=D ; save first popped value
@EQReturn2
D=A
@PopD
0; jmp
@EQReturn2:
; here D has 2nd popped value, R2 has first
@R2
D=D-M
@EQDone
equal; jmp
@AddressOfXFFFF
D=M
EQDone: ; D contains 0 or FFFF here
@R15
A=M ; fetch return address
0; jmp
综合起来:
@5 ; push constant 5
D=A
@R2
M=D
@returnaddress1
D=A
@pushR2
0 ; jmp
returnaddress1:
@X ; now push X
D=M
@R2
M=D
@returnaddress2
D=A
@pushR2
0 ; jmp
returnaddress2:
@returnaddress3 ; pop and compare the values
D=A
@EQ
0 ; jmp
returnaddress3:
此时,OP可以生成代码将D压入栈中:
@R2 ; push D onto stack
M=D
@returnaddress4
D=A
@pushR2
0 ; jmp
returnaddress4:
或者他可以生成代码以在 D 的值上分支:
@jmptarget
EQ ; jmp
关于algorithm - 如何为 Hack 汇编语言编写 'eq' 的解释器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30154665/
如何使下面的代码更简单、更少? 谢谢。 012 012 $('.btn div:eq(0)').click(function(){ $('.content div').hide();
新年快乐! 我正在努力学习 Racket(我不是经验丰富的 Lisper)。 现在我在 Racket 8.3 中遇到了以下问题: #lang racket > (define str1 "hello"
我最近开始学习 jQuery。考虑到以下html结构,我想知道选择器 $('ul>li:eq(2)') 和 $('ul>li').eq 之间的基本区别是什么(2). one two
IF :eq() 和 .eq() 是相同的功能,为什么是两种方法。有什么目的吗? 或者 哪里使用:eq()? 在哪里使用.eq()? 最佳答案 http://jsperf.com/eq-vs-eq 他
示例: $("td:eq(2)").css("color", "red"); or $('td').eq(2).css("color", "red"); 我想知道缩写“eq”代表什么,我不是问.eq(
为什么 ? Yes equals true. Yes does not equal true. 页面输出。 “是的就等于真的。” 最佳答案 Chris 和 Keshav 的答案是正确的,Cold
我对 Haskell 很陌生,在尝试编译 Frag 时遇到了这个错误。 src/AFRPVectorSpace.hs:51:25: Could not deduce (Eq a) arisin
我对 powershell 知之甚少。 我想知道是否有人可以指出我需要了解什么来解释以下内容: PS C:\Users\username> (Get-Aduser -Filter 'Enabled -
在使用 eq() 函数的示例中,它被用作 eq("+index+") 我以前从未见过这样的语法。两边的“+”号是什么意思?它与 eq(index) 有什么不同? 谢谢! 最佳答案 在 jQuery 中
我正在使用 cqlc 查询 cassandra。当我尝试运行 SELECT 语句时 ctx := cqlc.NewContext() iter, err := ctx.Select()
我希望能够推导出 Eq和 Show对于包含多个字段的 ADT。其中之一是功能字段。做的时候Show ,我希望它显示一些虚假的东西,例如"" ;做的时候Eq ,我希望它忽略该字段。在不为 Show 手写
我正在使用 jQuery 1.7.1,我试图找出为什么以下代码需要 4600 毫秒,如果我将 :eq(0) 更改为 :first 是一样的结果。 $("tr:eq(0) td"); // x10000
我正在尝试使用 Agda 解决以下一阶逻辑问题: problem : {A B : Set} {f : A → B} → inj f → ∀[ x ] ∀[ y ] (¬ Eq x y → ¬ E
我正在阅读一个haskell 教程(向你学习一个haskell 非常好),我正在玩我根据书中的一个函数编写的这段代码。 reverseNum :: (Num a) => a -> a reverseN
我正在处理一个页面,该页面具有可变数量的 .def-set 类元素。在某些页面上可能有多达 60 个,而在其他页面上可能只有 1 个。 我已经能够在 .def-set 类的第三个实例之后附加一个元素
我有一个来自 Learn You a Haskell for Great Good 的示例,名为 class Eq1 a where (===), (=/=) :: a -> a -> Bool
在 -eq 命令中包含多个值的语法是什么: 这有效,但我认为有一种方法可以节省一些输入: Get-Service | where {($_.Status -eq "Stopped") -OR ($_.
我们在实现 SCIM API 和让 Azure 在每种情况下都满意方面遇到了问题。Microsoft 试图为人们提供 configure how their active directory将映射到
我们在实现 SCIM API 和让 Azure 在每种情况下都满意方面遇到了问题。Microsoft 试图为人们提供 configure how their active directory将映射到
我的程序有问题。 我有一个比较两个字符串的条件: (if (eq? (exp1) (exp2))) 当 exp1 给我一个字符串,exp2 给我一个字符串。可以肯定的是,当我更改“eq?”时到“=”,
我是一名优秀的程序员,十分优秀!