对齐给定的指令,但将对齐填充放在指令之前以外的其他位置
Aligning a given instruction, but putting the alignment padding somewhere other than immediately before the instruction
是否有可能在 nasm(以及扩展名 yasm)中编写宏或以其他方式使用预处理器功能将某些特定指令与给定的 2 次方(或可能的给定次方)对齐两个加上一些偏移量),但插入对齐填充不是立即 在 指令之前,而是在任意更早的地方?
例如,假设您有一个函数,您希望将函数内部循环的顶部对齐 32,您可以这样做:
function:
xor eax, eax
mov ecx, 1
ALIGN 32
.top:
add eax, ecx
inc ecx
cmp ecx, rdi
jne .top
这将在 ALIGN 32
指令处执行一堆 nop
指令,这些指令将在进入循环之前执行(或者您可以跳过它们,但这仍然会执行一些操作为了跳过填充。
您不想在函数本身内添加填充,而是在永远不会执行的函数之前添加填充。例如,如果循环入口之前有 10 个字节,则将函数的顶部与 32N - 10
对齐即可。像这样:
padding_magic .top 32
function:
xor eax, eax
mov ecx, 1
ALIGN 32
.top:
add eax, ecx
inc ecx
cmp ecx, rdi
jne .top
是否有某种方法可以在 nasm 中实现它,即实现 padding_magic
?
好的,我想出了一个不太老套的方法来做到这一点。诀窍是 assemble 函数后的对齐填充,并依靠段排序将所有内容按正确顺序放置。
%macro BEGIN_PADDED_FUNC 0-1 16
%define _func_name %00
%define _align %1
%define _section_base .text.%[_func_name].
[SECTION %[_section_base]1 progbits alloc exec nowrite align=_align]
[SECTION %[_section_base]2 progbits alloc exec nowrite align=1]
_func_name:
%endmacro
%macro ALIGN_PADDED_FUNC 0
%[_func_name].align_point:
%endmacro
%macro END_PADDED_FUNC 0
[SECTION %[_section_base]1]
TIMES ((_align - (%[_func_name].align_point - _func_name) % _align) \
% _align) nop
__SECT__
%endmacro
上面的宏可以这样使用:
function BEGIN_PADDED_FUNC 32
xor eax, eax
mov ecx, 1
ALIGN_PADDED_FUNC
.top:
add eax, ecx
inc ecx
cmp ecx, edi
jne .top
END_PADDED_FUNC
此代码采用 ELF 和一个合理的链接器 and/or 链接器脚本,如果这是它们在目标文件中首次出现的顺序,它将在 .text.function.2
之前放置一个名为 .text.function.1
的部分。它可能可以修改为与 PECOFF 一起使用,但我还没有尝试过。我只用 NASM 测试过这个,我不知道这是否适用于 YASM。
是否有可能在 nasm(以及扩展名 yasm)中编写宏或以其他方式使用预处理器功能将某些特定指令与给定的 2 次方(或可能的给定次方)对齐两个加上一些偏移量),但插入对齐填充不是立即 在 指令之前,而是在任意更早的地方?
例如,假设您有一个函数,您希望将函数内部循环的顶部对齐 32,您可以这样做:
function:
xor eax, eax
mov ecx, 1
ALIGN 32
.top:
add eax, ecx
inc ecx
cmp ecx, rdi
jne .top
这将在 ALIGN 32
指令处执行一堆 nop
指令,这些指令将在进入循环之前执行(或者您可以跳过它们,但这仍然会执行一些操作为了跳过填充。
您不想在函数本身内添加填充,而是在永远不会执行的函数之前添加填充。例如,如果循环入口之前有 10 个字节,则将函数的顶部与 32N - 10
对齐即可。像这样:
padding_magic .top 32
function:
xor eax, eax
mov ecx, 1
ALIGN 32
.top:
add eax, ecx
inc ecx
cmp ecx, rdi
jne .top
是否有某种方法可以在 nasm 中实现它,即实现 padding_magic
?
好的,我想出了一个不太老套的方法来做到这一点。诀窍是 assemble 函数后的对齐填充,并依靠段排序将所有内容按正确顺序放置。
%macro BEGIN_PADDED_FUNC 0-1 16
%define _func_name %00
%define _align %1
%define _section_base .text.%[_func_name].
[SECTION %[_section_base]1 progbits alloc exec nowrite align=_align]
[SECTION %[_section_base]2 progbits alloc exec nowrite align=1]
_func_name:
%endmacro
%macro ALIGN_PADDED_FUNC 0
%[_func_name].align_point:
%endmacro
%macro END_PADDED_FUNC 0
[SECTION %[_section_base]1]
TIMES ((_align - (%[_func_name].align_point - _func_name) % _align) \
% _align) nop
__SECT__
%endmacro
上面的宏可以这样使用:
function BEGIN_PADDED_FUNC 32
xor eax, eax
mov ecx, 1
ALIGN_PADDED_FUNC
.top:
add eax, ecx
inc ecx
cmp ecx, edi
jne .top
END_PADDED_FUNC
此代码采用 ELF 和一个合理的链接器 and/or 链接器脚本,如果这是它们在目标文件中首次出现的顺序,它将在 .text.function.2
之前放置一个名为 .text.function.1
的部分。它可能可以修改为与 PECOFF 一起使用,但我还没有尝试过。我只用 NASM 测试过这个,我不知道这是否适用于 YASM。