64位汇编语言简介

x86-64位汇编语言简介
一、x86-64的寄存器
x86-64较x86-32多了8个通用寄存器,而且,每个通用寄存器都是64位宽,它们是:
rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp
r8,r9,r10,r11,r12,r13,r14,r15
同时,x86-64全面支持x86-32和x86-16的通用寄存器:
eax,ax,al,ah,
ebx,bx,bl,bh,
....
而且,还对传统的edi,esi做了改进:
edi ,32位
di,16位
dil ,8位,在传统的x86机器中,di是不可按照8位来访问的,但在x86-64下可以。
2018年中央一号文件同样esi也可以按照8位来访问。一个很特别的寄存器 rip,相当于x86-32的eip. 在x86-32是不可直接访问的,如mov eax,eip是错的,但在x86-64位下却可以,如 mov,rax,qword ptr [rip+100]是对的。而且,它除了是个程序计数器外,也是个“数据基地址”,有此可见,它现在是身兼两职!为什么在x86-64位下要用rip做访问数据的基地址呢?因为,在x86-64下,DS,ES,CS,SS都没有实际意义了,也就是说,它们不再参与地址计算,只是为了兼容x86-32。FS,GS还是参与地址计算,它们两个和x86-32的意义相同。
二、x86-64的汇编
x86-64的汇编和x86-32的没有多大的区别。添加了新寄存器和指令
写64位汇编代码时,可以用8、16、32、64位寄存器,如:
  push  rdi
  sub  rsp, 48              ;
  mov  r10, rcx
; Line 36
  mov  rdi, rdx
  xor  eax, eax
  mov  ecx, 512           
  rep stosb
; Line 43
  movsxd  r8, DWORD PTR [r10+16]
  mov  QWORD PTR [rsp+32], rdx
  mov  r9, QWORD PTR [r10+648]
  mov  rdx, QWORD PTR [r10+52]
  mov  rcx, QWORD PTR [r10+44]
  call  fs_read_disk
; Line 47
  mov  ecx, 1
  cmp  eax, ecx
  cmovne  ecx, eax
  mov  eax, ecx
; Line 52
  add  rsp, 48             
  pop  rdi
  ret  0
再如:
$L1818:
; Line 2398
  mov  al, BYTE PTR [rdx+rbx]
  cmp  al, 32             
  jne  SHORT $L1819
  mov  BYTE PTR [rdx+rbx], 0
$L1819:
  add  r8d, 1
  movsxd  rdx, r8d
  xor  eax, eax
水龙头oem
  mov  rcx, r12空城计剧本
农业生产资料管理办法
  mov  rdi, rbx
  repne scasb
  not  rcx
  sub  rcx, 1
  cmp  rdx, rcx
  jb  SHORT $L1818
但,有点值得注意,当操作传统的32位寄存器时,那么,整个64位寄存器都会受到影响,如:
mov eax,0ah
那么,rax也等于000000000000000ah
再如:
mov rcx,0aaaaaaaaaaaaaaaah
(此时ecx等于0aaaaaaaah)
mov ecx,0ddddddddh
(此时,rcx等于00000000ddddddddh,高32位受到了影响).
规则:
Example 1: 64-bit Add:
Before:RAX =0002_0001_8000_2201
RBX =0002_0002_0123_3301
ADD RBX,RAX ;48 is a REX prefix for size.
Result:RBX = 0004_0003_8123_5502
Example 2: 32-bit Add:
Before:RAX = 0002_0001_8000_2201
RBX = 0002_0002_0123_3301
ADD EBX,EAX ;32-bit add
Result:RBX = 0000_0000_8123_5502
(32-bit result is zero extended)
Example 3: 16-bit Add:
Before:RAX = 0002_0001_8000_2201
RBX = 0002_0002_0123_3301
ADD BX,AX ;66 is 16-bit size override
Result:RBX = 0002_0002_0123_5502
(bits 63:16 are preserved)
Example 4: 8-bit Add:
Before:RAX = 0002_0001_8000_2201
RBX = 0002_0002_0123_3301
ADD BL,AL ;8-bit add
Result:RBX = 0002_0002_0123_3302
(bits 63:08 are preserved)
三、指令集变化小结:
当然,这里说的都是最基本的东西,是针对通用寄存器言的。其实,x86-64对FPU(数学处理单元)和MMX,SSE,SSE2都做了很大的改进。然而,对写OS来说,我们最关心的还是
通用寄存器
1.地址宽度和操作数宽度前缀
    64位模式中,缺省的地址宽度是64位,缺省的操作数宽度是32位。地址宽度和操作数宽度前缀允许32位和64位数据和地址在指令序列中混用。下表(1-7)显示了在IA-32e模式下需要指令前缀地址宽度。注意,在64位模式下不支持16位地址。在敬爱内容和传统模式下,地址宽度函数的功能和在IA-32传动架构中一样。
下表(1-8)显示了66H指令前缀和REX.W前缀的有效组合来指定IA-32e操作模式下的操作数宽度问题。
    在64位模式下, 缺省的操作数宽度是32位,REX前缀包括4位域来指定16个不同的值。REX前缀的W位域指定为REX.W。REX.W=1时前缀表明操作数位64为操作数。注意,软件依然能使用操作数宽度66H前缀来切换到16位操作宽度。然而如果同时用REX.W和66H前缀,REX.W的优先权要高。
    在SSE/SSE2/SSE3 SIMD指令的情况下,66H, F2H和F3H前缀作为操作码扩展,并被
认为是指令的一部分。在这些情况下,有效的REX.W前缀和66H代码扩展前缀之间没有相互关系。
2.REX前缀
    REX前缀是64位模式下引入的新的指令前缀字节,他作以下工作:
•指定新的GPRs和SSE寄存器
•指定64位代码宽度
•指定扩展的控制寄存器(只给系统软件使用)
    不是所有的指令都需要REX前缀。这个前缀只在指令引用扩展的寄存器或使用64位操作数的时候才有必要。如果该前缀放在不需要的地方将会被忽略。
一个指令只能有一个REX前缀。这个前缀一旦使用,就必须直接放在操作码字节或两字节操作码扩展前缀之前。 其他位置的REX前缀将被忽略。
    包含有REX前缀的指令依然要遵循传统的15字节的指令宽度的限制。下图描述了REX前缀如何符合指令的字节次序的。
3.控制和调试寄存器的新编码
    在64位模式下,有为控制机存器和调试寄存器指定的附加的编码。当ModRM寄存器的域编码一个控制或调试寄存器的时候,REX.R位被用来修改这些域。这些编码允许处理器访问CR8-CR15和DR8-DR15。
    在64位模式中附加了一个控制寄存器(CR8)。CR8成为任务优先级寄存器(TPR)。在IA-32e技术的首次实现的时候,CR9-CR15和DR8-DR15都没有实现,对它们的访问将引起无效代码异常(#UD)。
4.新的指令抗体效价
    下面的新指令在带有64位扩展的64位模式下被引入。
•SWAPGS 指令
地面沉降•SYSCALL and SYSRET 指令
•CDQE 指令
•CMPSQ 指令
•CMPXCHG16B 指令
•LODSQ 指令
•MOVSQ 指令
•MOVZX(64-bits) 指令
•STOSQ 指令
5.堆栈指针
    在64位模式,堆栈指针为64位。堆栈大小不是像兼容模式或传统模式中那样靠SS段描述符中的某位来控制,也不通过指令前缀来指示。
    对隐式堆栈引用将忽略地址大小的指示。除远分支以外,所有隐式引用RSP的指令在64位模式下缺省为64位操作数。影响到的指令包括:PUSH, POP, PUSHF, POPF, ENTER, 和LEAVE。使用这些指令在64位模式下将不可能产生32位堆栈值的压栈和退栈。如果使用66H操作数前缀,将支持16位的压栈和退栈。
    当寄存器RAX-RSP被用作操作数的时候,64位模式缺省的操作尺寸无需REX前缀作为这些指令的先导。如果式R8-R15作为操作数,则REX依然是需要的。这是因为前缀在访问新扩展寄存器中是需要的。
6.分支转移
    64位扩展技术扩充2个分支机制来适应64位线性地址空间的分支。他们是:
•64位模式下近分支转移被重新定义
•在64位模式和兼容模式下,64位调用门描述符定义成远调用
    64位模式下,所有近分支转移(CALL, RET, JCC, JCXZ, JMP 和 LOOP)被强迫为64位。
这些指令被更新为提供64位的RIP值而无需REX前缀。下面的近转移被有效的操作数宽度所控制:
•指令指针的宽度的截断
•由于CALL或RET引起的退栈压栈或退栈的大小
•由于CALL或RET而引起的堆栈指针增加或减少的大小
•间接转移操作数大小
    在64位模式下,以上的所有操作都被强制为64位而不管操作数前缀(操作数大小的前缀被忽略)。然而相对转移的位移区域依然受到32位的限制;近转移的地址大小没有被强制为64位。

本文发布于:2024-09-20 15:32:12,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/648592.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:前缀   指令   宽度   地址   寄存器   模式   扩展
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议