在 x86 汇编的例程中,如果代码包含指向两个有效地址之间的有效地址的跳转,会发生什么情况?这是一个人为的例子:
0x0001: mov ...
0x0005: add ...
0x0009: jmp 0x0003
Run Code Online (Sandbox Code Playgroud)
此外,我如何在本地计算机或在线上进行类似的实验?我检查了在线x86编辑器,如https://defuse.ca/online-x86-assembler.htm#disassemble,但它不允许我输入“0x0001”等指令地址。
从https://www.keil.com/support/man/docs/armasm/armasm_dom1361289866046.htm中读取arm-thumb指令的blx指令可以支持最大4MB的跳转范围。
但据我所知,arm-thumb指令只有16位长,那么16位怎么能包含4MB的偏移量呢?
我最初试图生成立即移动到 64 位寄存器的字节。我想要的具体操作是
mov rdi, 0x1337
Run Code Online (Sandbox Code Playgroud)
使用https://www.felixcloutier.com/x86/mov,我看到的唯一非符号扩展指令是
REX.W + B8+ rd io
Run Code Online (Sandbox Code Playgroud)
这让我很困惑,所以我创建了一个小型汇编程序来查看汇编器会生成什么
global _start
section .text
_start:
mov rdi, 0x1337
syscall
mov rax, 60
xor rdi, rdi
syscall
Run Code Online (Sandbox Code Playgroud)
我必须关闭优化,以便迁移到 64 位寄存器。所以我编译nasm -felf64 -O0 main.asm && ld main.o并生成了一个a.out. 我看着objdump -M intel -d ./a.out这行
48 bf 37 13 00 00 00 movabs rdi,0x1337
Run Code Online (Sandbox Code Playgroud)
那条线看起来一点也不像
REX.W + B8+ rd io
Run Code Online (Sandbox Code Playgroud)
大部头书?另外,经过一些研究,我发现该命令应该是 10 个字节。你如何从 得到它REX.W + B8+ rd io?
I386指令集中的“Grpl”指令的作用是什么?我正在学习计算机指令并做指令模拟实验。在模拟的过程中我遇到了这样的指令83 F8 01。
为了了解如何使用该指令,我查阅了 i386 手册中的附录 a 操作码映射。由于该指令的操作码为83,所以我找到了操作码映射条目:
\n
但我不知道GRPL是什么意思,也不知道CPU是做什么的。我检查了Intel 80386指令集,但找不到该指令的描述。以 E 开头的指令后面直接跟着以 H 开头的指令。 (enter和hlt)
我还查了谷歌,找不到该命令的描述。由于不知道这条指令的实际含义,我无法模拟它。CPU是如何实现这个功能的呢?正确的查询是什么?我错过了什么\xef\xbc\x9f
\n我是逆向工程的新手,我想了解更多,我试图反汇编一个目标exe,我遇到了一些我无法解释的函数.希望有人帮忙可以伸出援助之手.
00161000 /$ 83EC 08 SUB ESP,8
00161003 |. 6A 00 PUSH 0 ; /pHandle = NULL
00161005 |. 68 A8311600 PUSH Launcher.001631A8 ; |FileName =
0016100A |. E8 81160000 CALL <JMP.&VERSION.GetFileVersionInfoSiz>; \GetFileVersionInfoSizeW
0016100F |. 890424 MOV DWORD PTR SS:[ESP],EAX
00161012 |. 85C0 TEST EAX,EAX
00161014 |. 0F84 97000000 JE Launcher.001610B1
0016101A |. 56 PUSH ESI
0016101B |. 57 PUSH EDI
0016101C |. 8B3D 8C301600 MOV EDI,DWORD PTR DS:[<&KERNEL32.GetProc>; kernel32.GetProcessHeap
00161022 |. 50 PUSH EAX ; /HeapSize
00161023 |. 6A …Run Code Online (Sandbox Code Playgroud) 排除将一种高级语言转换为另一种语言的编译器,编译为机器代码的编译器是否需要用汇编编写?
compiler-construction programming-languages machine-code low-level
所以我一直在使用Chip-8模拟器作为我的CompSci类的最终项目,并且遇到了一个似乎超出我的代码的问题.我下载的大量演示(我确信它们是真正的Chip-8程序,而不是SuperChip或类似的东西)包含的机器指令不符合任何Chip-8操作码的格式.
http://mattmik.com/files/chip8/mastering/chip8.html
在页面的底部是所有操作码的列表,每个操作码长2个字节,以及它们中的每个半字节数字代表什么.但是,相当数量的程序具有不符合任何指令格式的指令.例如,这是一个来自其中一个的十六进制转储 - 我会在其中指出一些个别情况
0000000 6a 00 6b 04 6c 01 6d 00 6e 02 23 26 23 20 60 30
0000010 61 01 f0 15 f0 07 f1 18 30 00 12 14 22 42 23 20
0000020 7d 01 23 20 60 08 e0 a1 23 0a 4a 00 12 3e a3 62
0000030 d8 91 79 01 d8 91 4f 01 12 f4 49 18 12 e4 22 b2
0000040 12 1e 4c 01 22 6c …Run Code Online (Sandbox Code Playgroud) 经过几个小时的研究,我没有找到一个具体的答案来解决我的问题而且我要疯了!
从编辑到执行的步骤:
1.(编译步骤)编写源代码后,编译程序.在此步骤中,它将转换为字节码.生成java.class文件(字节码).
2.(执行步骤)现在我执行程序.
现在的步骤是:代码 - >字节码 - >执行 - >机器码
所有这些步骤都与硬件和软件无关. 我对吗?
这称为JIT(只是及时编译),因此当我执行程序时,字节码被编译成机器码,然后才编译. 那么为什么这一步称为解释?
我提前感谢你的答案!
在英特尔软件开发人员手册中,第2A章2.1.2节说明了这一点
用于通用和SIMD指令的双字节操作码格式包括以下之一:
- 转义操作码字节0FH作为主操作码和第二操作码字节.
- 强制前缀(66H,F2H或F3H),转义操作码字节和第二个操作码字节(与前一个子弹相同).
什么是'逃避操作码',它的目的是什么?
当将x设置为零(x = 0)时,我的csapp书指出了两种方法。
第一:
xorq %rcx, %rcx
Run Code Online (Sandbox Code Playgroud)
第二:
movq $0, %rcx
Run Code Online (Sandbox Code Playgroud)
它还表明第一个仅占用3个字节,而第二个仅占用7个字节。
两种方式如何运作?为什么第一个字节比第二个字节少?