使用 Rust 内联汇编时奇怪的机器代码字节顺序
Weird machine code bytes order when using Rust inline assembly
我目前正在尝试用 Rust(Windows 32 位)编写一个程序,它基本上会从它自己的 .text 部分中提取一些特定的机器代码部分。
基本上,如果我将函数 test1
定义并调用为:
unsafe fn test1(){
asm!("
pushad
.byte 0x90, 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90
inc eax
mov eax, ebx
xor eax, eax
.byte 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90, 0x90
popad
"
:
:
:
:"intel");
}
它将输出:
inc eax
mov eax, ebx
xor eax, eax
程序使用.byte 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90, 0x90
和.byte 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90, 0x90
来识别要检索的代码(这些操作码代表一些nop
和or reg, reg
,它们基本上什么都不做)。
一切正常,直到我尝试执行以下操作:
unsafe fn test2(){
asm!("
.byte 0x90, 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90
"
:
:
:
:"intel");
while a < 10{
a += 1;
}
asm!("
inc eax
dec eax
.byte 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90, 0x90
"
:
:
:
:"intel");
}
它只检测到 inc/dec
指令,这意味着我看不到任何可能与两种内联汇编用法之间的 Rust 代码等效的汇编代码(递增 [=35 的 while 循环) =]a).
我真的不知道 Rust 编译器如何处理内联汇编,但我从逻辑上认为它会遵守代码必须执行的顺序...
我希望我的问题足够清楚。
在优化的输出中,除了在其间执行的程序集将具有相同的可观察效果之外,基本上没有任何保证。这意味着不能保证顺序或程序集看起来与输入完全一样。 (众所周知,编译器会将某些循环计算序列转换为其等效的求和函数)。
如果要在优化汇编中定位与一段代码关联的程序集,请将该代码放在它自己的函数中,并将该函数及其调用的所有函数标记为no_inline。并确保您希望看到的所有代码都具有可观察到的效果,或者使用 benchmark::black_box 假装它具有。
我目前正在尝试用 Rust(Windows 32 位)编写一个程序,它基本上会从它自己的 .text 部分中提取一些特定的机器代码部分。
基本上,如果我将函数 test1
定义并调用为:
unsafe fn test1(){
asm!("
pushad
.byte 0x90, 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90
inc eax
mov eax, ebx
xor eax, eax
.byte 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90, 0x90
popad
"
:
:
:
:"intel");
}
它将输出:
inc eax
mov eax, ebx
xor eax, eax
程序使用.byte 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90, 0x90
和.byte 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90, 0x90
来识别要检索的代码(这些操作码代表一些nop
和or reg, reg
,它们基本上什么都不做)。
一切正常,直到我尝试执行以下操作:
unsafe fn test2(){
asm!("
.byte 0x90, 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90
"
:
:
:
:"intel");
while a < 10{
a += 1;
}
asm!("
inc eax
dec eax
.byte 0x90, 0x09, 0xC0, 0x09, 0xDB, 0x09, 0xC9, 0x90, 0x90
"
:
:
:
:"intel");
}
它只检测到 inc/dec
指令,这意味着我看不到任何可能与两种内联汇编用法之间的 Rust 代码等效的汇编代码(递增 [=35 的 while 循环) =]a).
我真的不知道 Rust 编译器如何处理内联汇编,但我从逻辑上认为它会遵守代码必须执行的顺序...
我希望我的问题足够清楚。
在优化的输出中,除了在其间执行的程序集将具有相同的可观察效果之外,基本上没有任何保证。这意味着不能保证顺序或程序集看起来与输入完全一样。 (众所周知,编译器会将某些循环计算序列转换为其等效的求和函数)。
如果要在优化汇编中定位与一段代码关联的程序集,请将该代码放在它自己的函数中,并将该函数及其调用的所有函数标记为no_inline。并确保您希望看到的所有代码都具有可观察到的效果,或者使用 benchmark::black_box 假装它具有。