【问题标题】:Alignment of stack variables in Assembly Languages汇编语言中堆栈变量的对齐
【发布时间】:2023-01-03 09:52:51
【问题描述】:

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

例如,假设 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 -> DWORD -> WORD -> BYTE

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

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

【问题讨论】:

  • MASM 实际上有点不寻常,因为它有 LOCAL 指令来为您计算这些东西。对于大多数汇编程序,您将只需要手动计算堆栈帧偏移量并对其进行硬编码。通常,用汇编编写的要点是你想自己做所有的优化;汇编程序的工作是准确地编码您编写的内容,否则就不会妨碍您。

标签: assembly gcc masm


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2012-04-05
    • 2013-11-05
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    相关资源
    最近更新 更多