第88章 npad

“npad”指令是一种汇编宏,用于把下一个指令标签的首地址向指定边界对齐。

被npad指令对齐的标签,通常都是需要被多次跳转到的地址标签。例如,在各种循环体起始地址处的标签之前,我们经常可以看到npad指令。它可通过对齐内存地址、内存总线或缓存线等手段,提高CPU加载数据(或指令代码)的访问效率。

下面这段代码摘自MSVC的文件listing.inc。

顺便提一下,这都是NOP指令的变种。虽然这些指令没有实际的操作意义,但是它们可以占用不同的空间。

出于CPU性能的考虑,下述代码没有使用多条NOP指令,而是使用了单条指令。

;; LISTING.INC
;;
;; This file contains assembler macros and is included by the files created
;; with the -FA compiler switch to be assembled by MASM (Microsoft Macro
;; Assembler).
;;
;; Copyright (c) 1993-2003, Microsoft Corporation. All rights reserved.
 
;; non destructivenops
npad macro size
if size eq 1
   nop
else
  if size eq 2
    mov edi, edi
  else
  if size eq 3
     ; lea ecx, [ecx+00]
     DB 8DH, 49H, 00H
  else
    if size eq 4
     ; lea esp, [esp+00]
     DB 8DH, 64H, 24H, 00H
   else
     if size eq 5
       add eax, DWORD PTR 0
     else
      if size eq 6
        ; lea ebx, [ebx+00000000]
       DB 8DH, 9BH, 00H, 00H, 00H, 00H
      else
        if size eq 7
          ; lea esp, [esp+00000000]
          DB 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H
         else
           if size eq 8
            ; jmp .+8; .npad 6
            DB 0EBH, 06H, 8DH, 9BH, 00H, 00H, 00H, 00H
           else
           if size eq 9
            ; jmp .+9; .npad 7
            DB 0EBH, 07H, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H
           else
            if size eq 10
             ; jmp .+A; .npad 7; .npad 1
            DB 0EBH, 08H, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 90H
           else
            if size eq 11
             ; jmp .+B; .npad 7; .npad 2
             DB 0EBH, 09H, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 8BH, 0FFH
            else
             if size eq 12
              ; jmp .+C; .npad 7; .npad 3
              DB 0EBH, 0AH, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 8DH, 49H, 00H
             else
              if size eq 13
               ; jmp .+D; .npad 7; .npad 4
               DB 0EBH, 0BH, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 8DH, 64H, 24H, 00H
              else
               if size eq 14
               ; jmp .+E; .npad 7; .npad 5
               DB 0EBH, 0CH, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 05H, 00H, 00H, 00H, 00H
              else
               if size eq 15
                ; jmp .+F; .npad 7; .npad 6
                DB 0EBH, 0DH, 8DH, 0A4H, 24H, 00H, 00H, 00H, 00H, 8DH, 9BH, 00H, 00H, 00H, 00H
               else
                %out error: unsupported npad size
                .err
               endif
              endif
             endif
            endif
           endif
          endif
         endif
        endif
       endif
      endif
     endif
    endif
   endif
  endif
 endif
endm