我一直在尝试使用此页面以及其他各种指南来弄清楚如何将非常简单的ARM指令表达为二进制和十六进制.对我来说这似乎应该是一个简单的过程,但我仍然不明白.这是一些例子.
基本NOP:
what goes here? what goes here?
_?_ _____?____
| | | |
mov r0, r0 ; ????00?1101?????????????????????
|__||__|
? ?
how do I express registers?
Run Code Online (Sandbox Code Playgroud)
其他人的基本问题相同.
比较两个寄存器:
cmp r1, r0
Run Code Online (Sandbox Code Playgroud)
立即添加寄存器值:
add r0, #0x1a
Run Code Online (Sandbox Code Playgroud)
所有这些在线教程都非常出色地描述了如何使用这些指令,但是我找不到任何实际的指令实际上是如何将ARM指令转换为汇编它的二进制/十六进制/机器代码.
在此先感谢您的帮助.
前几天我遇到了这个看似非常简单的问题如何在不引用$ array1的情况下更改$ array2中的值?然而,我越是调查它就越奇怪,它似乎确实按预期运作.在此之后,我开始研究从以下输出生成的操作码.
$array1 = array(2, 10);
$x = &$array1[1];
$array2 = $array1;
$array2[1] = 22;
echo $array1[1]; // Outputs 22
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很疯狂,因为array2应该只是array1的副本,并且发生在一个数组中的任何内容都不应该影响另一个数组的内容.当然,如果你注释掉第二行,最后一行将像预期的那样回应10.
看得更远,我可以在一个很酷的网站上向我展示PHP使用Vulcan Logic Dumper生成的操作码.这是上面代码生成的操作码.
Finding entry points
Branch analysis from position: 0
Return found
filename: /in/qO86H
function name: (null)
number of ops: 11
compiled vars: !0 = $array1, !1 = $x, !2 = $array2
line # * op fetch ext return operands
---------------------------------------------------------------------------------
3 0 > INIT_ARRAY ~0 2
1 ADD_ARRAY_ELEMENT ~0 10
2 ASSIGN !0, ~0 …
Run Code Online (Sandbox Code Playgroud) 有没有办法将特定的立即字节大小的数字'移动到直接内存位置?即
MOV 10h,ffffh
Run Code Online (Sandbox Code Playgroud)
将值16
写入内存地址65535
?如果是,那是哪个操作码,或者我是否必须先将存储器地址存入寄存器?
我正在考虑将第三方库移植到.NET for Windows Store应用程序.该库通过调用ILGenerator.Emit方法重载过度使用System.Reflection.Emit.OpCodes.
在.NET for Windows Store Apps API中,包含了OpCode
结构和OpCodes
类,但没有ILGenerator
类,并且我已经找不到替换.
我显然失去了一些东西,但:没有ILGenerator
一流的,什么是包括的目的System.Reflection.Emit.OpCode
和OpCodes
在.NET的Windows Store应用程序的API?
我正在为优秀的旧GameBoy开发一个模拟器,我正面临一些问题,如何必须实现一些基本的操作代码.
现在我正在实施AND操作; 前几个(0xA0 - > 0xA3; 0xA6和0xA7)非常简单,但寄存器H,L的AND操作有点不同.
您可以在以下链接下载z80的文档: um0080.pdf(第172页)
这里有一些例子来说明我的意思(使用伪代码),基本上我做了什么:
AND A,H(注意位移)
(read HL register; >> 8) save in cache C
R->C = R->HL >> 8;
perform AND operation with cache
AND_H(R->C);
R->A &= R->C;
Run Code Online (Sandbox Code Playgroud)
和A,L(注意位屏蔽)
(read HL register; &0xFF) save in cache C
R->C = R->HL &0xFF;
Run Code Online (Sandbox Code Playgroud)
我知道所有的位操作,我知道他们做了什么,但似乎我无法弄清楚为什么需要这样做.我有一些理论(如果我错了,请纠正我:-)):
我已经理解的是,寄存器H和L基本上是寄存器HL,它是一个16位寄存器.由于CPU /总线只能处理8位操作,因此需要将其拆分; 或更多的逻辑建议:由于它只有一个寄存器,H和L的值在寄存器中被屏蔽,它们只需要彼此分开(高/低半字节?).
如果有人能够让我更清楚,我会非常感激,因为我只想拥有更多的背景知识(所有这些内容如何在内部运作),所以对我来说非常重要,因为我知道自己在做什么.
我再次提出另一个无关紧要的Z80问题:-)我的仿真器内核当前的结构方式,每次从内存中取出操作码字节时,我都会递增内存刷新寄存器的低7位 - 这意味着对于多字节指令,例如作为开始DD或FD的那些,我将寄存器递增两次 - 或者在诸如RLC(IX + d)之类的指令的实例中递增三次(因为它布局为opcode1-opcode2-d-opcode3).
它是否正确?我不确定 - Z80手册有点不清楚,因为它说CPDR(一个双字节指令)将它增加两倍,但是"存储器刷新寄存器"部分仅表示它在每次取指令后递增.我注意到J80(我检查过的模拟器,因为我不确定)只在指令的第一个操作码字节后递增.
哪个是对的?我想这在任何情况下都不是非常重要,但是很高兴知道:-)非常感谢.
此致,菲尔波特
我注意到在程序段中使用了代码段.
例:
MOV DWORD PTR SS:[EBP-30],30
Run Code Online (Sandbox Code Playgroud)
我认为"PTR SS:"用于指定EBP-30来自堆栈?(SS:堆栈段)我是对还是我完全错了?:)那么,请你告诉我上面的例子与之间的区别
MOV DWORD PTR[EBP-30],30
Run Code Online (Sandbox Code Playgroud)
那么在操作码中使用的DS(数据段)呢?
在阅读JVM规范时(就像我一样),当我遇到7个iconst_<i>
操作码时,我感到非常惊讶.毕竟,只有一个字节可以播放.
我很少在代码中写入2,3,4或5的文字.我可以理解为什么-1,0和1可能会被特别对待,但我觉得设计师想要将4个珍贵的操作码吹到恰好相当小的数字上似乎很神奇.
有谁知道这是否有充分理由?我低估了这些的好处吗?
我目前正在对smali /"代码混淆器"进行一些研究,我正试图熟悉目前反编译的源代码.为此,我创建了一个简单的应用程序,并由smali反编译.
我现在正试图理解反编译的源代码,以便在以后使用代码混淆器后改进并比较安全性(反编译).虽然大多数小型源代码并不那么困难,但我有时会遇到数字格式转换的问题.
你可以向我解释一下如下.我猜它应该有五个值,但我不确定,这是哪种二进制格式.如何计算它0x4014 = 5 ???
const-wide/high16 v0, 0x4014 // 100000000010100 (5 = 101)
Run Code Online (Sandbox Code Playgroud)
附件是此测试函数的完整java和smali代码源:
Java来源:
boolean test(int a, double d) {
if (a < 5 && d < 5)
return true;
else
return false;
}
Run Code Online (Sandbox Code Playgroud)
Smali来源:
.method test(ID)Z
.locals 2
.parameter "a"
.parameter "d"
.prologue
.line 28
const/4 v0, 0x5
if-ge p1, v0, :cond_0
const-wide/high16 v0, 0x4014
cmpg-double v0, p2, v0
if-gez v0, :cond_0
.line 29
const/4 v0, 0x1
.line 31
:goto_0
return v0
:cond_0
const/4 v0, 0x0 …
Run Code Online (Sandbox Code Playgroud)