我正在尝试调用本机机器语言代码.这是我到目前为止(它得到一个总线错误):
char prog[] = {'\xc3'}; // x86 ret instruction
int main()
{
typedef double (*dfunc)();
dfunc d = (dfunc)(&prog[0]);
(*d)();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它确实正确地调用了函数并且它到达了ret指令.但是当它试图执行ret指令时,它有一个SIGBUS错误.是因为我在一个未清除执行的页面上执行代码或类似的东西?
那么我在这里做错了什么?
这是周末,所以我通过写一个爱好项目来度过整周的编程.
我昨天编写了一个MOS 6502 CPU仿真器的框架,实现了寄存器,堆栈,内存和所有操作码.(链接到下面的来源)
我可以在我编写的调试器中手动运行一系列操作,但是我想加载一个NES rom并按指令指向程序计数器,我认为这是找到有缺陷的操作码的最快方法.
我写了一个快速的NES rom加载程序并将ROM库加载到CPU内存中.
问题是我不知道操作码是如何编码的.我知道操作码本身遵循每个操作码一个字节的模式,该模式唯一地标识操作码,
0 - BRK
1 - ORA (D,X)
2 - COP b
Run Code Online (Sandbox Code Playgroud)
等等
但是我不确定我应该在哪里找到操作码参数.是直接跟随的字节吗?在绝对记忆中,我想它可能不是一个字节而是一个短.
有人熟悉这个CPU的内存模型吗?
编辑:我意识到这可能是在黑暗中拍摄,但我希望有一些老学校的苹果和Commodore黑客潜伏在这里.
编辑:感谢大家的帮助.在我实施适当的更改以对齐每个操作后,CPU可以加载并运行Mario Brothers.除了循环等待Start之外它什么也没做,但它是一个好兆头:)
我上传了这个来源:
http://www.codeplex.com/Cpu6502/SourceControl/DirectoryView.aspx?SourcePath=&changeSetId=1810
如果有人想知道模拟器是如何工作的,那么它很容易理解.至少没有优化,但是再次,我在2.4ghz机器上模拟一个以2mhz运行的CPU :)
什么使编程语言的所有单词实际上做了什么?我的意思是,实际上发生了什么让计算机知道所有这些词的含义是什么?如果我口头告诉我的电脑做某事,它就不会这样做,因为它不明白.那么,这些人类用语言写成文字究竟是如何让计算机做出一些理想的活动呢?
我正在为IDA的大型Amiga项目进行逆向工程,我取得了很大的进步.但是,有一些我无法弄清楚的东西.也就是说,我发现了几个使用我认为是"跳转表"的子程序 - 但我无法弄清楚它们是如何工作的.有人有建议吗?
moveq #0,d0
move.b d7,d0 ; set D0 to a byte from CTRL
subq.w #1,d0 ; subtract 1 from it
blt.w finish_29ABA ; if D0 is less than 1, branch
cmpi.w #$16,d0
bge.w finish_29ABA ; if D0 is greater than or equal to 16, branch
add.w d0,d0 ; otherwise, double D0
move.w dword_29918(pc,d0.w),d0
jmp dword_29918+2(pc,d0.w)
; ---------------------------------------------------------------------------
dword_29918: dc.l $400036 ; CODE XREF: serialCtrlCmd+E0j
dc.l $360036
dc.l $3601A0
dc.l $3601A0
dc.l $1A001A0
dc.l $360040
dc.l $2A01A0
dc.l $400036 …Run Code Online (Sandbox Code Playgroud) 例如,当我编译一个C应用程序时,输出的文件读取为二进制或操作系统然后解释编译?"机器语言"是纯二进制吗?
编辑:是的,计算机上的所有内容都是纯二进制文件.我询问处理器是否直接解释编译器输出的文件,还是操作系统首先处理它?
设置,读取,移动和比较等操作是否需要同时执行?
如果没有:有没有办法找出多久.
我的意思是什么名称,某些特定类型cpu执行不同汇编语言指令的速度(移动,读取等)
使用amd64汇编,最好的方法是将64位寄存器的前32位清零,例如将未覆盖的rax位清零?似乎我不能和整个寄存器对64位常数.
我正在尝试学习使用 cortex m0 处理器。我有一个 stm32f0 开发板,它可以让我查看每个地址的每一位并轻松上传新的二进制文件。我一直在阅读大量手册,了解许多规则和功能,但仍然不知道程序计数器在重置时从哪里开始,它期望什么类型的参数,我什至不知道如何编写诸如 add 之类的东西或二进制形式的 str/ldr。我读过的手册中是否遗漏了这些基本知识?
它说 m0 有一个完整的降序堆栈,但它似乎表明起点在另一端(0x00000000)。如果向量表也可以用外行的术语来解释,那就太好了。
如何访问可执行文件的机器代码(二进制文件)?
细节
我无法弄清楚LEGv8机器指令是如何解码的.假设以下二进制文件:
1000 1011 0000 1111 0000 0000 0001 0011
我有以下图表可以帮助我解码:
前11位10001011000对应于十进制1112,根据图表,这是ADD指令.所以我知道如何确定指令的这一部分(除非有更好的方法,这可能不适用于非11位的操作码?).在这一点上,我对如何继续感到困惑.
我知道ADD是指令格式的R格式,因此位的布局如下:
操作码:11比特
Rm:5比特
shamt:6比特
Rn:5比特
Rd:5比特
我试图在知道这些字段大小的情况下布置初始二进制机器指令...
操作码= 1000 1011 000 0 1111 0000 0000 0001 0011 = 10001011000
这是初始二进制机器指令的前11位.
Rm = 1000 1011 000 0 1111 0000 0000 0001 0011 = 01111
这是操作码的初始11位之后的下5位.
shamt = 1000 1011 0000 1111 0000 00 00 0001 0011 = 000000
这是Rm的5位之后的下6位.
Rn = 1000 1011 0000 1111 0000 00 00 000 1 0011 = …
assembly machine-language instruction-set instructions arm64