Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 在x86汇编中,每条指令编译成多少个“是”?_Assembly_X86_Gnu Assembler_Instruction Set - Fatal编程技术网

Assembly 在x86汇编中,每条指令编译成多少个“是”?

Assembly 在x86汇编中,每条指令编译成多少个“是”?,assembly,x86,gnu-assembler,instruction-set,Assembly,X86,Gnu Assembler,Instruction Set,字节数是相邻指令之间的地址差: push %ebp mov %esp,%ebp sub $0x28,%esp 0x004012d0:推送%ebp;1字节 0x004012d1:mov%esp,%ebp;2字节 0x004012d3:低于$0x28,%esp 如果只有文本,则转到此处:和此处:并计算每条指令、前缀和操作数如果汇编代码为文本,则必须使用汇编程序例程来获取 二进制表示,因此指令的大小。当然,这取决于硬件 例如,这里有一个open()。第一条指令位于[main+0],

字节数是相邻指令之间的地址差:

push   %ebp
mov    %esp,%ebp
sub    $0x28,%esp
0x004012d0:推送%ebp;1字节
0x004012d1:mov%esp,%ebp;2字节
0x004012d3:低于$0x28,%esp

如果只有文本,则转到此处:和此处:并计算每条指令、前缀和操作数

如果汇编代码为文本,则必须使用汇编程序例程来获取
二进制表示,因此指令的大小。当然,这取决于硬件


例如,这里有一个open()。

第一条指令位于[main+0],第二条位于[main+1],因此第一条指令为1字节。第三条指令位于[main+3],因此第二条指令是两个字节。您无法从清单中看出第三条指令有多长,因为它没有显示4的地址。指令。

您不必根据助记符确定指令大小。以下是一些特殊情况:

  • 如果在16位段中,
    mov eax,0
    需要
    0x66
    前缀,而在32位段中则不需要。您需要知道段的大小

  • 在32位或16位模式下,您可以将
    addeax,1
    编码为
    0x40
    inceax
    )或
    0x83 0xc0 0x01
    addeax,1
    )。也就是说,有些助记符可以用多种方式编码

  • 内存操作数
    [eax]
    可以将
    eax
    编码为基或索引。如果它是索引,那么在MOD/RM之后将有一个额外的SIB字节

  • 在64位模式下,您可以使用REX前缀
    0x4x
    对寄存器
    r8
    -
    r15
    进行编码。但是,您可以使用
    0x40
    作为某种类型的null REX字节,这将在指令中添加另一个字节

  • 即使显式段与隐式段相同,也可以使用段替代


还有许多其他方法可以使用更多或更少的字节对指令进行编码。一个好的汇编程序应该总是使用最短的汇编程序,但它肯定不是体系结构所要求的。好的方面是,如果您学习《英特尔IA-32软件开发人员手册》第2卷,您应该能够自己完成。

如果可能,请汇编程序生成一个清单。这将显示您的源代码,接下来是指令的二进制表示,您需要做的就是计算有多少字节,然后得到大小。

您想在运行时使用它吗?ie
asm\U大小(“mov esp,ebp”)
?这种东西依赖于硬件架构。这不是一个“分析”问题,而是一个“查找合适的“字典”问题。在Linux中,您可以使用
objdump-d可执行文件
查看操作码,然后您将看到每个指令索引的大小,指令编码,特别是在x86/x64上,是不明确的,两者都是指两个汇编助记符可以描述同一条指令(
xchg ax,ax
nop
),一个汇编助记符可能有两个二进制操作码(
inc eax
,32位-都
0x40
0xff 0xc0
)。它们有时甚至出于某种原因故意含糊不清,比如
NOP
指令,请看,许多旧指令也可以用VEX或EVEX前缀重新编码,因此它们将有多个不同的表示形式length@L乌夫·恩霍克:这不太准确。使用VEX或EVEX编码为AVX的SSE指令的行为略有不同:*它们具有不同的启用要求。例如,VEX需要CR4.OSXSAVE和XCR0中的各种位。*128位AVX指令清除YMM或ZMM的高位,而相应的SSE指令保持高位不变
push   %ebp
mov    %esp,%ebp
sub    $0x28,%esp
0x004012d0 <main+0>:    push   %ebp ;1 byte
0x004012d1 <main+1>:    mov    %esp,%ebp ;2 bytes
0x004012d3 <main+3>:    sub    $0x28,%esp