gpt4 book ai didi

assembly - 对齐节的开头是什么意思?

转载 作者:行者123 更新时间:2023-12-02 14:27:44 31 4
gpt4 key购买 nike

对齐节的开头是什么意思?

例如:

 align 4
a: dw 0

它如何节省内存访问?

最佳答案

我一直喜欢 Samael 在以下帖子中的全面解释:
Explanation of the ALIGN MASM directive, How is this directive interpreted by the compiler?

引用:

1。用法

ALIGN X

ALIGN 指令附有一个数字 (X)。
这个数字 (X) 必须是 2 的幂。即 2、4、8、16 等等...

该指令允许您在该指令之后立即强制对齐指令或数据,该内存地址是值 X 的倍数。

在前一个指令/数据和 ALIGN 指令之后的指令/数据之间的额外空间,在代码段的情况下用 NULL 指令(或等效指令,例如 MOV EAX,EAX)填充,在以下情况下用 NULL 填充数据段。

数字 X 不能大于引用 ALIGN 指令的段的默认对齐方式。它必须小于或等于段的默认对齐方式。更多相关内容请关注...

2.目的

A.使用代码

如果指令位于代码之前,原因可能是优化(引用执行速度)。如果某些指令在 4 字节(32 位)边界上对齐,则执行速度会更快。这种优化通常可以在时间关键的函数中使用或引用,例如为不断操作大量数据而设计的循环。不过,除了执行速度提高之外,没有“必要”在代码中使用该指令。

B.处理数据

对于数据也是如此 - 我们主要使用指令来提高执行速度 - 作为速度优化的一种手段。在某些情况下,数据不一致会对我们的应用程序产生巨大的性能影响。

但对于数据来说,在某些情况下正确对齐是必要的,而不是奢侈的。这在 Itanium 平台和 SSE/SSE2 指令集上尤其如此,其中 128 位边界 (X=16) 上的未对齐可能会引发一般保护异常。

下面是一篇关于数据对齐的有趣且信息最丰富的文章,尽管它是针对 MS C/C++ 编译器的:

Windows Data Alignment on IPF, x86, and x64, by Kang Su Gatlin, MSDN

3.段的默认对齐方式是什么?

A. 如果您使用 .386 处理器指令,并且尚未显式声明段的默认对齐值,则默认段对齐为 DWORD(4 字节)大小。是的,在这种情况下,X = 4。然后,您可以将以下值与 ALIGN 指令一起使用:(X=2, X= 4)。请记住,X 必须小于或等于段对齐方式。

B. 如果您使用 .486 及以上处理器指令,并且尚未显式声明段的默认对齐值,则默认段对齐为 PARAGRAPH(16 字节)大小。在本例中,X = 16。然后,您可以将以下值与 ALIGN 指令结合使用:(X=2、X= 4、X = 8、X = 16)。

C. 您可以通过以下方式声明具有非默认对齐方式的段:

;Here, we create a code segment named "JUNK", which starts aligned on a 256 bytes boundary 
JUNK SEGMENT PAGE PUBLIC FLAT 'CODE'

;Your code starts aligned on a PAGE boundary (X=256)
; Possible values that can be used with the ALIGN directive
; within this segment, are all the powers of 2, up to 256.

JUNK ENDS

这是段对齐值的别名...

Align Type     Starting Address 

BYTE Next available byte address.
WORD Next available word address (2 bytes per word).
DWORD Next available double word address (4 bytes per double word).
PARA Next available paragraph address (16 bytes per paragraph).
PAGE Next available page address (256 bytes per page).

4。示例

考虑以下示例(阅读有关 ALIGN 指令用法的注释)。

.486 
.MODEL FLAT,STDCALL
OPTION CASEMAP:NONE

INCLUDE \MASM32\INCLUDE\WINDOWS.INC

.DATA

var1 BYTE 01; This variable is of 1 byte size.
ALIGN 4

; We enforce the next variable to be alingned in the next memory
;address that is multiple of 4.
;This means that the extra space between the first variable
;and this one will be padded with nulls. ( 3 bytes in total)

var2 BYTE 02; This variable is of 1 byte size.

ALIGN 2
; We enforce the next variable to be alingned in the next memory
;address that is multiple of 2.
;This means that the extra space between the second variable
;and this one will be padded with nulls. ( 1 byte in total)

var3 BYTE 03; This variable is of 1 byte size.

.CODE
; Enforce the first instruction to be aligned on a memory address multiple of 4
ALIGN 4

EntryPoint:
; The following 3 instructions have 7 byte - opcodes
; of the form 0F B6 05 XX XX XX XX
; In the following block, we do not enforce opcode
; alignment in memory...

MOVZX EAX, var1
MOVZX EAX, var2
MOVZX EAX, var3

; The following 3 instructions have 7 byte - opcodes
; of the form 0F B6 05 XX XX XX XX
; In the following block, we enforce opcode alignment
; for the third instruction, on a memory address multiple of 4.
; Since the second instruction opcodes end on a memory address
; that is not a multiple of 4, some nops would be injected before
; the first opcode of the next instruction, so that the first opcode of it
; will start on a menory address that is a multiple of 4.


MOVZX EAX, var1
MOVZX EAX, var2
ALIGN 4
MOVZX EAX, var3

; The following 3 instructions have 7 byte - opcodes
; of the form 0F B6 05 XX XX XX XX
; In the following block, we enforce opcode alignment
; for all instructions, on a memory address multiple of 4.
;The extra space between each instruction will be padded with NOPs

ALIGN 4
MOVZX EAX, var1
ALIGN 4
MOVZX EAX, var2
ALIGN 4
MOVZX EAX, var3


ALIGN 2
; The following instruction has 1 byte - opcode (CC).
; In the following block, we enforce opcode alignment
; for the instruction, on a memory address multiple of 2.
;The extra space between this instruction ,
;and the previous one, will be padded with NOPs

INT 3
END EntryPoint

如果我们编译该程序,编译器会生成以下内容:

.DATA
;------------SNIP-SNIP------------------------------
.data:00402000 var1 db 1
.data:00402001 db 0; This NULL was generated to enforce the alignment of the next instruction on an address that is a multiple of 4
.data:00402002 db 0; This NULL was generated to enforce the alignment of the next instruction on an address that is a multiple of 4
.data:00402003 db 0; This NULL was generated to enforce the alignment of the next instruction on an address that is a multiple of 4

.data:00402004 var2 db 2
.data:00402005 db 0; This NULL was generated to enforce the alignment of the next instruction oon an address that is a multiple of 2

.data:00402006 var3 db 3

.data:00402007 db 0; The rest of the NULLs are to fill the memory page in which the segment will be loaded
;------------SNIP-SNIP------------------------------

.CODE
;------------SNIP-SNIP------------------------------

.text:00401000 start:
.text:00401000 movzx eax, var1
.text:00401007 movzx eax, var2
.text:0040100E movzx eax, var3
.text:00401015 movzx eax, var1
.text:0040101C movzx eax, var2
.text:00401023 nop; This NOP was generated to enforce the alignment...
.text:00401024 movzx eax, var3
.text:0040102B nop; This NOP was generated to enforce the alignment...
.text:0040102C movzx eax, var1
.text:00401033 nop; This NOP was generated to enforce the alignment...
.text:00401034 movzx eax, var2
.text:0040103B nop; This NOP was generated to enforce the alignment...
.text:0040103C movzx eax, var3
.text:00401043 nop; This NOP was generated to enforce the alignment...
.text:00401044 int 3 ; Trap to Debugger
.text:00401044; ---------------------------------------------------------------------------
.text:00401045 db 0
.text:00401046 db 0
.text:00401047 db 0
.text:00401048 db 0

;------------SNIP-SNIP------------------------------

正如你所看到的,当我们的应用程序的代码/数据结束后,编译器会生成更多的指令/数据。这是因为当加载到内存中时,PE 部分是按页大小(512 字节)对齐的。

因此,编译器用垃圾字节(通常是 INT 3 指令、代码段的 NOP 或 NULL,以及数据段的 0FFh、NULL)填充下一个 512 字节边界的额外空间,以确保内存对齐加载的PE镜像是正确的...

关于assembly - 对齐节的开头是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11277652/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com