在开发 86-DOS 应用程序lDebug的分支期间,我遇到了称为“Intel 组”的指令类别。具体来说,组是指与使用相同 1 或 2 个操作码字节的一组指令相关的东西,通过/rModR/M 字节的字段来区分。
“Intel 组”类别可以一直追溯到 1997 年发布的 FreeDOS Debug 0.95,并且可以在我的 fddebug 存储库的修订版中看到:
/*
* Here are the tables for the main processor groups.
*/
struct {
int seq; /* sequence number of the group */
int info; /* which group number it is */
}
grouptab[] = {
{0x80, GROUP(1)}, /* Intel group 1 */
{0x81, GROUP(1)},
{0x83, GROUP(2)},
{0xd0, GROUP(3)}, /* Intel group 2 */
{0xd1, GROUP(3)},
{0xd2, …Run Code Online (Sandbox Code Playgroud) 0x042444FF; /* inc dword ptr [esp+4] */
Run Code Online (Sandbox Code Playgroud)
0x042444FF是机器代码,虽然inc dword ptr [esp+4]是汇编代码,但我知道机器代码不是跨平台的,因为它取决于很多因素.
汇编代码怎么样,它取决于CPU?
如果我有一个包含已编译 C 代码的二进制可执行文件,我是否可以使用十六进制编辑器来编辑该二进制文件并将特定指令更改为另一个指令,例如nop或jmp?我如何知道我要更改的指令的偏移量?
是的,这是出于教育目的。
在英特尔文档"架构软件开发人员手册Vol 2A"中,表2-4显示了REX前缀位的重要性.
有人可以向我解释当W = 0时如何解释?它说,0 = Operand size determined by CS.D但我不明白是什么CS.D意思.
我已经在Google上寻找了一种可以在汇编源文件中包含机器代码的方法.我没有运气.
我所说的'内联机器代码'可能不清楚,所以让我给你一个我正在寻找的例子:
; here's my normal assembly code...
mov eax, 8
add eax, 10
; now I would like to be able to add some machine code
__machinecode__("40") ; this is equivalent to 'inc eax' (I think!)
Run Code Online (Sandbox Code Playgroud)
就是这样了.
我有一个简单的程序集程序
.text
.globl _start
_start:
movl $1, %eax
movl $1, %ebx
int $0x80
Run Code Online (Sandbox Code Playgroud)
我已经组装好了.我已将其内容转储如下
root@bt:~# objdump -d out
out: file format elf32-i386
Disassembly of section .text:
08048054 <_start>:
8048054: b8 01 00 00 00 mov $0x1,%eax
8048059: bb 01 00 00 00 mov $0x1,%ebx
804805e: cd 80 int $0x80
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,如果只给出下面的机器代码,我能否找回助记符 \xb8\x01\x00\x00\x00\xbb\x01\x00\x00\x00\xcd\x80
我正在用MSVC++中的机器代码进行一些实验,并创建了一个函数,允许我在带有符号位移的寄存器周围构建mov操作.一切顺利,直到我的功能建立起来mov [esp-4], eax.突然,我的程序开始崩溃了.在看完拆卸后,我发现了一些相当奇怪的东西.对于此mov取消引用ESP寄存器的偏移量,在参数字节和有符号位移之间放置了一个额外的字节.这个字节似乎总是0x24.因此,出于好奇,我拆解了下面的__asm块并获得了一些有趣的结果:
mov [eax - 4], eax
mov [ecx - 4], eax
mov [edx - 4], eax
mov [ebx - 4], eax
mov [esp - 4], eax
mov [ebp - 4], eax
mov [esi - 4], eax
mov [edi - 4], eax
Run Code Online (Sandbox Code Playgroud)
机器代码将上述内容翻译成:
89 40 FC
89 41 FC
89 42 FC
89 43 FC
89 44 24 FC <--- WAT!
89 45 FC
89 46 FC
89 47 FC
Run Code Online (Sandbox Code Playgroud)
我在Windows计算器中键入了十六进制24并将其切换为二进制.结果是 …
这让我困惑的原因是所有地址都保持1和0的序列.那么CPU如何00000100从00000100(CPU指令)中区分(整数)?
我在一台8位PC上观看了一个视频 - 手动,使用物理开关.
美联储的计划是:
MAIN:
0000 0001 0100 # 0 = LDA [4]
0001 0010 0101 # 1 = ADD [5]
0010 0101 0000 # 2 = OUT
0011 1111 0000 # 3 = HLT
DATA:
0100 00001110 # 4 = #14
0101 00011100 # 5 = #28
Run Code Online (Sandbox Code Playgroud)
我想知道的是计算机如何区分数据和指令,因为没有标记可以从指令中划分数据.
0001 0001 0010可以解释为:
1 = LDA [2]
Run Code Online (Sandbox Code Playgroud)
要么:
1 = #10
Run Code Online (Sandbox Code Playgroud)
是因为在程序运行时,地址被视为指令.但由于HLT,程序停止执行内存地址,就像它们是指令一样,并留下更高的地址; 然后LDA/ADD/SUB等将内存中的所有位置视为二进制值.
在那种情况下,会:
0000 0010 0000可解释为:
0 = ADD #32
Run Code Online (Sandbox Code Playgroud)
并不是
0 = ADD [ ADD [ ADD [ …Run Code Online (Sandbox Code Playgroud)