x86_64 ASM - 指令的最大字节数?

时间:2013-02-05 00:47:06

标签: c assembly x86 64-bit x86-64

x64 asm代码中完整指令需要的最大字节数是多少?

跳转到地址可能会占用多达9个字节,我想: FF 00 00 00 00 11 12 3F 1F 但我不知道这是否是x64指令的最大字节数可以使用

3 个答案:

答案 0 :(得分:35)

x86指令集(16,32或64位,所有变体/模式)保证/要求指令最多15个字节。除此之外的任何内容都会产生“无效的操作码”。如果不使用冗余前缀(例如,多个0x66或0x67前缀),则无法实现此目的。

实际需要64位作为数据项的唯一指令是要注册的负载常量(英特尔语法:mov reg, 12345678ABCDEF00h,并且语法为:movabs $12345678ABCDEF00, %reg) - 所以如果你想要跳转向前/向后超过31位,它将是目标位置移动到寄存器中,然后调用/跳转到寄存器。使用32位立即数和位移(在相对跳转和寻址模式下)可以在64位模式下在许多指令上保存四个字节。

答案 1 :(得分:23)

  

问题,x86指令集中最长的指令是什么?

     

答案:您可以使用无限字节数形成有效的x86指令!

     

没错,你可以用一条有效的指令填充整个64K ROM图像。更具体地说,8086指令的长度没有限制。凉!不幸的是,现代i386变体在尝试解码超过15个字节的指令时会引发一般性保护错误。

     

那么无限长但有效的8086指令是什么样的呢?实际上有点无聊。您只能通过在操作码前面使用冗余前缀来形成无限长的指令。指令前缀是预先写入指令开头的字节,可以修改指令使用的默认地址大小,数据大小或段寄存器。

     

例如,你可以采取看似无害的指示:

89 E5              mov %sp,%bp
     

把它变成一条很长的指令:

66 66 66 66 … 66 66 89 E5                mov %sp,%bp
     

现在那只是邪恶。

https://web.archive.org/web/20131109063453/https://www.onlinedisassembler.com/blog/?p=23


另一条不重复前缀的长指令

  

在某些情况下,可以编码超过传统15字节长度限制的有效指令。例如:

  ; 16-bit mode
  F2 F0 36 66 67 81 84 24 disp32 imm32 =  xaquire lock add [ss:esp*1+disp32],imm32
  F3 F0 36 66 67 81 84 24 disp32 imm32 = xrelease lock add [ss:esp*1+disp32],imm32

  ; 16-bit mode
  36 67 8F EA 78 12 84 24 disp32 imm32 = lwpins eax,[ss:esp*1+disp32],imm32
  36 67 8F EA 78 12 8C 24 disp32 imm32 = lwpval eax,[ss:esp*1+disp32],imm32
  36 67 8F EA 78 10 84 24 disp32 imm32 =  bextr eax,[ss:esp*1+disp32],imm32

  ; 64-bit mode
  64 67 8F EA F8 12 84 18 disp32 imm32 = lwpins rax,[fs:eax+ebx+disp32],imm32
  64 67 8F EA F8 12 8C 18 disp32 imm32 = lwpval rax,[fs:eax+ebx+disp32],imm32
  64 67 8F EA F8 10 84 18 disp32 imm32 =  bextr rax,[fs:eax+ebx+disp32],imm32

http://www.sandpile.org/x86/opc_enc.htm

答案 2 :(得分:15)

来自英特尔®64和IA-32架构软件开发人员手册:

  

2.3.11 AVX指令长度

     

Intel 64和IA-32指令的最大长度保持为15   字节。

您可以构造编码超过15个字节的指令,但这些指令可能是非法的,可能不会执行。