使用 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来识别要检索的代码(这些操作码代表一些nopor 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 假装它具有。