汇编语言中栈变量的对齐



是否有任何汇编指令来对齐特定的堆栈数据变量?

例如,假设一个MASM函数有这些初始值为 的局部变量
LOCAL           beginStack:QWORD         ; ffffffffdeadbeef
LOCAL           myLocalA:QWORD           ; ffffffffffffffff
LOCAL           myLocalB:QWORD           ; 0000000000000000
LOCAL           myArrayA[10]:BYTE        ; AAAAAAAAAA
LOCAL           myArrayB[10]:BYTE        ; BBBBBBBBBB
LOCAL           endStack:QWORD           ; ffffffffbaadf00d

内存堆栈有这样的布局,但注意endStack是不对齐的

00000048`51effb60 baadf00d000906ec  ; baadf00d
00000048`51effb68 42424242ffffffff  ; ffffffff
00000048`51effb70 4141424242424242 
00000048`51effb78 4141414141414141 
00000048`51effb80 0000000000000000 
00000048`51effb88 ffffffffffffffff 
00000048`51effb90 ffffffffdeadbeef 

对齐endStack,我试图将局部变量与对齐pad[4]混合

LOCAL           beginStack:QWORD
LOCAL           myLocalA:QWORD
LOCAL           myLocalB:QWORD
LOCAL           myArrayA[10]:BYTE
LOCAL           myArrayB[10]:BYTE
LOCAL           pad[4]:BYTE
LOCAL           endStack:QWORD

正确对齐endStack

0000005b`950ff950 ffffffffbaadf00d  ; aligned
0000005b`950ff958 42424242ffdaf38f  ; pad[4] is ffdaf38f
0000005b`950ff960 4141424242424242 
0000005b`950ff968 4141414141414141 
0000005b`950ff970 0000000000000000 
0000005b`950ff978 ffffffffffffffff 
0000005b`950ff980 ffffffffdeadbeef 

另一种方法(如果适用)是根据降序层次结构重新洗牌堆栈变量
QWORD->DWORDWORDBYTE

GCC有这个__attribute__ ((aligned (8)))来对齐变量,但是否有汇编语言的等效方法?

感觉像C/c++这样的高级语言有一个很大的优化技巧工具箱,但不幸的是没有移植到较低级的汇编语言。

目前为止的部分答案是定义一个MASM宏aligned,它向DWORD和WORD变量插入填充字节,使它们在64位中保持8字节对齐。

这个粗宏接受一个DWORD或WORD变量,然后决定填充字节数。为了防止重复的符号错误,它定义了一个本地num,它在每次调用宏时生成唯一的标签。输出是局部变量本身,后跟填充符:DWORD为LOCAL pad??0001[4], WORD为LOCAL pad??0001[6]

aligned MACRO var
LOCAL num
IF @InStr(1,<var>,<:DWORD>) NE 0
padBytes = 4
ELSEIF @InStr(1,<var>,<:WORD>) NE 0
padBytes = 6
ENDIF
var
@CatStr(<LOCAL pad>,<num>,<[padBytes]:BYTE>)
ENDM

为了与其他C/c++对齐保持类似,LOCAL的前缀是aligned宏调用

main proc   
aligned LOCAL AppleA:WORD
aligned LOCAL AppleB:DWORD    
aligned LOCAL AppleC:WORD
aligned LOCAL AppleD:DWORD      

LOCAL OrangeA:WORD
LOCAL OrangeB:DWORD    
LOCAL OrangeC:WORD
LOCAL OrangeD:DWORD         

mov AppleA,1
mov AppleB,2
mov AppleC,3
mov AppleD,4   

mov OrangeA,5
mov OrangeB,6
mov OrangeC,7
mov OrangeD,8      

ret
main endp
end

运行代码的内存堆栈显示

00000030`f1b1fb10 00077ff600000008   ; OrangeD 8 is misaligned
00000030`f1b1fb18 00057ff600000006   ; OrangeB 6 is misaligned
00000030`f1b1fb20 000000040000001f   ; AppleD 4 is aligned
00000030`f1b1fb28 0003000000000000   ; AppleC 3 is aligned
00000030`f1b1fb30 0000000200000000   ; AppleB 2 is aligned
00000030`f1b1fb38 00017ff6915ae298   ; AppleA 1 is aligned

指出

如注释所述,这个宏还不能解析数组。一个解决方案是使用MASM MOD运算符,当expression1除以expression2时,返回余数(取模)的整数值。我们的想法是接受一个数组,比如aligned LOCAL myArrayA[10]:BYTE,提取10的arraySize,然后使用

计算所需的填充字节6
padBytes = (8 - (arraySize MOD 8))

Michael Petch提出了一个非常聪明和独特的方法,将所有的局部元素放在一个结构中。一个结构可以接受一个对齐值(例如:8或QWORD),它将相应地对齐元素。这是一点额外的工作,但它会达到目的。示例如下:pastebin.com/4cLWm0f1

.code
main PROC
main_locs STRUC QWORD           ; 8 byte (QWORD) alignment
beginStack DQ ?
myLocalA   DQ ?
myLocalB   DQ ?
myArrayA   BYTE 10 DUP (?)
myArrayB   BYTE 10 DUP (?)
endStack   DQ ?
main_locs ENDS
LOCAL stack_vars: main_locs

lea rcx, stack_vars
mov [rcx][main_locs.beginStack], 0ffffffffdeadbeefh
mov [rcx][main_locs.myLocalA],   0ffffffffffffffffh
mov [rcx][main_locs.myLocalB],   00000000000000000h
;Fill myArrayA with 10 As
mov rax, "AAAAAAAA"
mov QWORD PTR[rcx][main_locs.myArrayA], rax
mov WORD  PTR[rcx][main_locs.myArrayA+8], ax
;Fill myArrayB with 10 Bs
mov rax, "BBBBBBBB"
mov QWORD PTR[rcx][main_locs.myArrayB], rax
mov WORD  PTR[rcx][main_locs.myArrayB+8], ax
mov [rcx][main_locs.endStack], 0ffffffffbaadf00dh
ret
main ENDP

end

最新更新