内联汇编器中的预递增

问题描述 投票:0回答:1

我正在尝试使b = ++ a;在内联汇编器中运行,但是在执行代码后得到奇怪的变量值。我正在使用clang(与GCC兼容)来编译嵌入式汇编程序。这是到目前为止我得到的:

#include <iostream>

using std::endl;
using std::cout;

int main()
{
    uint64_t a = 0;
    uint64_t b = 0;

    asm volatile(
    "pushq %%rbp;"
    "movq %%rsp, %%rbp;"
    "movl $0, -4(%%rbp);"
    "movl $0, -8(%%rbp);"
    "addq $1, -4(%%rbp);"
    "mov -4(%%rbp), %%rax;"
    "mov %%rax, -8(%%rbp);"
    "mov -4(%%rbp), %0;"
    "mov -8(%%rbp), %1;"
    "movq %%rbp, %%rsp;"
    "popq %%rbp"
    :"=r" (a), "=r" (b)
    :
    :"%rax", "%rbp", "%rsp"
    );
    cout << "a = " << a << ", b = " << b << endl;
    return 0;
}
macos x86 x86-64 inline-assembly clang++
1个回答
-3
投票

您可以在不使用内联汇编器的情况下编写代码

#include <iostream>

using std::endl;
using std::cout;

int main()
{
    uint64_t a = 0;
    uint64_t b = 0;

    b = ++a;
    cout << "a = " << a << ", b = " << b << endl;
    return 0;
}

并创建它的汇编代码:

__cxx_global_var_init:                  # @__cxx_global_var_init
        pushq   %rbp
        movq    %rsp, %rbp
        movabsq $_ZStL8__ioinit, %rdi
        callq   std::ios_base::Init::Init() [complete object constructor]
        movabsq $_ZNSt8ios_base4InitD1Ev, %rax
        movq    %rax, %rdi
        movabsq $_ZStL8__ioinit, %rsi
        movabsq $__dso_handle, %rdx
        callq   __cxa_atexit
        popq    %rbp
        retq
main:                                   # @main
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $32, %rsp
        movl    $0, -4(%rbp)
        movq    $0, -16(%rbp)
        movq    $0, -24(%rbp)
        movq    -16(%rbp), %rax
        addq    $1, %rax
        movq    %rax, -16(%rbp)
        movq    %rax, -24(%rbp)
        movabsq $_ZSt4cout, %rdi
        movabsq $.L.str, %rsi
        callq   std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        movq    -16(%rbp), %rsi
        movq    %rax, %rdi
        callq   std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned long)
        movq    %rax, %rdi
        movabsq $.L.str.1, %rsi
        callq   std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        movq    -24(%rbp), %rsi
        movq    %rax, %rdi
        callq   std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned long)
        movq    %rax, %rdi
        movabsq $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %rsi
        callq   std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))
        xorl    %ecx, %ecx
        movq    %rax, -32(%rbp)         # 8-byte Spill
        movl    %ecx, %eax
        addq    $32, %rsp
        popq    %rbp
        retq
_GLOBAL__sub_I_example.cpp:             # @_GLOBAL__sub_I_example.cpp
        pushq   %rbp
        movq    %rsp, %rbp
        callq   __cxx_global_var_init
        popq    %rbp
        retq
.L.str:
        .asciz  "a = "

.L.str.1:
        .asciz  ", b = "

使用https://godbolt.org/,您可以找到相应的代码部分。内联汇编程序的可能代码是

#include <iostream>

using std::endl;
using std::cout;

int main()
{
    uint64_t a = 0;
    uint64_t b = 0;

    asm volatile(
        "movq    -16(%rbp), %rax;"
        "addq    $1, %rax;"
        "movq    %rax, -16(%rbp);"
        "movq    %rax, -24(%rbp);"
    );
    cout << "a = " << a << ", b = " << b << endl;
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.