每个asm指令的大小是多少?每条指令占用多少字节?8个字节?四个用于操作码,四个用于参数?例如,当你在mov中有一个操作码和2个参数时会发生什么?它们在内存中是否具有固定大小或它们是否有所不同?EIP是否与此有关,它的值总是加1,完全独立于它所经过的指令类型?
我问这个当我正在阅读http://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames时,我偶然发现,看起来调用指令相当于push和jmp指令.
call MYFUNCTION
mov my_var, eax
Run Code Online (Sandbox Code Playgroud)
和...一样
push [eip + 2];
jmp MYFUNCTION;
mov my_var, eax
Run Code Online (Sandbox Code Playgroud)
当我们在堆栈上推动[eip + 2]时,我们指向的值是什么?到"jmp MYFUNCTION"旁边的行,移动my_var eax,对吧?
ps:MSVC++在第一行标记错误,因为它表示eip未定义.它适用于eax,esp,ebp等.我做错了什么?
在32位模式下,英特尔通过反转寄存器扩展的高位来解决VEX前缀与LDS/LES冲突,因为ModRM字节的mod字段不能为11b
VEX前缀的初始字节值C4h和C5h与LDS和LES指令的操作码相同.64位模式不支持这些指令.为了在32位模式下解决模糊性,VEX的规范利用了合法的LDS或LES的ModRM字节不能是11xxxxxx(它将指定寄存器操作数)的事实.VEX前缀的第二个字节中的各个位字段被反转,以确保该字节在32位模式下始终为此形式.
https://en.wikipedia.org/wiki/VEX_prefix#Technical_description
但是在EVEX中,R和X位不反转,导致mod = 00b,这也表示BOUND指令中的内存操作数
来自REX前缀的四位R,X,B和W. W将操作数大小扩展为64位或作为附加操作码,R扩展reg,B扩展r/m或reg,X和B扩展索引和SIB字节中的基址.与VEX前缀相比,RXB以非反转形式提供,就像在REX前缀中一样.
那么他们如何能够干净地解码该指令?
我查看了英特尔手册,他们似乎只提到了VEX中的位反转,而不是EVEX.
OTOH表中的沙堆说,在这些EVEX RxB位也应该被反转.
哪一项是正确的?
我正在查看汇编中的不同指令,我对如何决定不同操作数和操作码的长度感到困惑.
这是你应该从经验中得知的东西,还是有办法找出哪个操作数/运算符组合占用了多少字节?
例如:
push %ebp ; takes up one byte
mov %esp, %ebp ; takes up two bytes
Run Code Online (Sandbox Code Playgroud)
所以问题是:
在看到给定的指令后,如何推断出其操作码需要多少字节?
所以我正在阅读一篇论文,其中他们说静态反汇编二进制代码是不可判定的,因为一系列字节可以用图片(其 x86 )所示的尽可能多的方式表示
所以我的问题是:
那么CPU如何执行呢?例如在图中,当我们到达 C3 之后,它如何知道下一条指令应该读取多少字节?
CPU如何知道在执行一条指令后PC应该增加多少?它是否以某种方式存储当前指令的大小并在它想要增加 PC 时添加它?
如果 CPU 能够以某种方式知道它应该为下一条指令读取多少字节或者基本上如何解释下一条指令,为什么我们不能静态地做到这一点?
x86 ×5
assembly ×4
code-size ×1
cpu ×1
disassembly ×1
instructions ×1
machine-code ×1
opcode ×1