问题描述
对齐节的开头是什么意思?
What is the meaning of align an the start of a section?
例如:
align 4
a: dw 0
它如何保存内存访问权限?
How does it save memory access?
推荐答案
我一直喜欢Samael在以下主题中提供的全面解释:
解释ALIGN MASM指令,编译器如何解释该指令?
I always liked the comprehensive explanation by Samael in the following thread:
Explanation of the ALIGN MASM directive, How is this directive interpreted by the compiler?
报价:
ALIGN X
ALIGN指令附带数字(X).
这个数字(X)必须是2的幂.即2、4、8、16,依此类推...
The ALIGN directive is accompanied by a number (X).
This number (X) must be a power of 2. That is 2, 4, 8, 16, and so on...
伪指令允许您在伪指令之后立即在内存地址(其值是X的倍数)上强制对齐指令或数据.
The directive allows you to enforce alignment of the instruction or data immediately after the directive, on a memory address that is a multiple of the value X.
在代码段的情况下,前一条指令/数据与ALIGN指令后的之间的多余空间用NULL指令(或等效的内容,例如MOV EAX,EAX)填充,在代码段的情况下用NULL填充.数据段.
The extra space, between the previous instruction/data and the one after the ALIGN directive, is padded with NULL instructions (or equivalent, such as MOV EAX,EAX) in the case of code segments, and NULLs in the case of data segments.
数字X不能大于引用ALIGN指令的段的默认对齐方式.它必须小于或等于线段的默认对齐方式.更多有关此内容的信息……
The number X, cannot not be greater than the default alignment of the segment in which the ALIGN directive is referenced. It must be less or equal to the default alignment of the segment. More on this to follow...
A.使用代码
如果指令在代码之前,则原因是优化(参考执行速度).如果某些指令在4字节(32位)的边界上对齐,则执行速度会更快.这种优化通常可以在对时间要求严格的功能中使用或引用,例如对经常处理大量数据而设计的循环.但是,除了提高执行速度外,没有必要"将指令与代码一起使用.
If the directive precedes code, the reason would be optimization (with reference to execution speed) . Some instructions are executed faster if they are aligned on a 4 byte (32 bits) boundary.This kind of optimization can be usually used or referenced in time-critical functions, such as loops that are designed for manipulating large amount of data, constantly.Besides execution speed improvement, there is no "necessity" to use the directive with code, though.
B.处理数据
数据也是如此-我们主要使用指令以提高执行速度-作为速度优化的一种手段.在某些情况下,数据未对齐会对我们的应用程序产生巨大的性能影响.
The same holds true also with data - we mainly use the directive in order to improve execution speed - as a means of speed optimization. There are situations where data misalignment can have a huge performance impact on our application.
但是,有了数据,在某些情况下,正确对齐是必要的,而不是奢侈的.在Itanium平台和SSE/SSE2指令集上尤其如此,在128位边界(X = 16)上的未对齐可能会触发通用保护异常.
But with data, there are situations where correct alignment is a necessity, not luxury. This holds especially true on the Itanium platform and the SSE/SSE2 instruction set, where misalignment on a 128bit boundary (X=16), may fire up a general-protection exception.
尽管是针对MS C/C ++编译器的,但有关数据对齐的有趣且最有用的文章是:
An interesting and most informative article on data alignment, though orientated on the MS C/C++ compiler, is the following:
在IPF,x86和x64上的Windows数据对齐,由MSDN的Kang Su Gatlin
A..如果使用.386处理器指令,并且尚未显式声明段的默认对齐方式值,则默认的段对齐方式为DWORD(4字节)大小.是的,在这种情况下,X = 4.然后,可以将以下值与ALIGN指令一起使用:(X = 2,X = 4).请记住,X必须小于或等于段对齐.
A. If you use the .386 processor directive, and you havent explicitly declared the default alignment value for a segment, the default segment alignment is of DWORD (4 bytes) size.Yeah, in this case, X = 4.You can then use the following values with the ALIGN directive: (X=2, X= 4).Remember, X must be less or equal than the segment alignment.
B.如果您使用.486及以上的处理器指令,并且尚未显式声明段的默认对齐方式值,则默认的段对齐方式为PARAGRAPH(16字节)大小.在这种情况下,X = 16.然后,您可以在ALIGN指令中使用以下值:(X = 2,X = 4,X = 8,X = 16).
B. If you use the .486 processor directive and above, and you havent explicitly declared the default alignment value for a segment, the default segment alignment is of PARAGRAPH (16 bytes) size.In this case, X = 16.You can then use the following values with the ALIGN directive: (X=2, X= 4, X = 8, X = 16).
C .您可以通过以下方式声明具有非默认对齐方式的细分:
C. You can declare a segment with non-default alignment in the following way:
;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
以下是细分受众群匹配度值的别名...
Here are the aliases for segment aligment values...
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指令用法的注释).
4. Example
Consider the following example (read the comments on the usage of the ALIGN directive).
.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
如果我们编译程序,则编译器将生成以下内容:
If we compile the program, here's what the compiler generated:
.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部分在加载到内存中时按照PAGE大小(512字节)对齐.
As you see, after the code / data of our application ends, the compiler generates more instructions / data. This is because the PE sections, when loaded in memory, are aligned on a PAGE size (512 bytes).
因此,编译器用垃圾字节(通常为INT 3指令,对于代码段为NOP或NULL,对于数据段为0FFh,NULL)填充到下一个512字节的末尾空间,以确保内存对齐加载的PE图像正确...
So, the compiler, fills the extra space to the next 512 byte boudary with junk bytes (usually INT 3 instructions, NOPs or NULLs for code segments, and 0FFh, NULLs for data segments) in order to ensure that the memory alignment for the loaded PE image is correct...
这篇关于对齐节的开头是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!