c++ - 如果我移动一个值来注册和编辑它会有什么不同

标签 c++ inline-assembly

最近我决定开始使用内联汇编和 C++ 编写代码..

我正在尝试像这样将数组长度归零:

void PrintAsm(void* Array, int Count)
{
    __asm
    {
        cmp Count, 0
            jle Done
            jg LoopArray

        LoopArray :
        mov byte ptr[Array], 0
            inc Array
            dec Count
            jnz LoopArray
            jmp Done

        Done :
    }
}


int main()
{
    char* Array = new char[10]; 

    for (int i(0); i < 10; i++) Array[i] = (char)rand();

    for (int i (0); i < 10; i++) std::cout << (int)Array[i] << " ";
    
    PrintAsm(Array, 10);

    std::cout << "\n\n";

    for (int i(0); i < 10; i++) std::cout << (int)Array[i] << " ";

    delete[] Array;

    std::cout << "\n\n";

    system("PAUSE");

    return 0;
}

输出:

41 35 -66 -124 -31 108 -42 -82 -82 -112

41 35 -66 -124 -31 108 -42 -82 -82 -112

直到我真正将数组保存在一个寄存器中并将计数保存在另一个寄存器中之前,它才起作用:

void PrintAsm(void* Array, int Count)
{
    __asm
    {
        mov ecx, Array
        mov edx, Count
        cmp edx, 0
        jle Done
        jg LoopArray

    LoopArray:
        mov byte ptr[ecx], 0
        inc ecx
        dec edx
        jnz LoopArray
        jmp Done

    Done:
    }
}

int main()
{
    char* Array = new char[10]; 

    for (int i(0); i < 10; i++) Array[i] = (char)rand();

    for (int i (0); i < 10; i++) std::cout << (int)Array[i] << " ";
    
    PrintAsm(Array, 10);

    std::cout << "\n\n";

    for (int i(0); i < 10; i++) std::cout << (int)Array[i] << " ";

    delete[] Array;

    std::cout << "\n\n";

    system("PAUSE");

    return 0;
}

输出:

41 35 -66 -124 -31 108 -42 -82 -82 -112

0 0 0 0 0 0 0 0 0 0

代码仍然是一样的,但是将它保存在寄存器中修复了它,如何?

我已经修复了它,但这让我想知道,这与直接编辑值有什么不同?

最佳答案

I'm trying to zero array length just like ...

相关的,这是我使用的,因为 GCC 的潜在问题及其对 volatile 限定符含义的解释。

// g++ -Og -g3 -m64 wipe.cpp -o wipe.exe
// g++ -Og -g3 -m32 wipe.cpp -o wipe.exe

// g++ -Os -g2 -S -m64 wipe.cpp -o wipe.exe.S
// g++ -Os -g2 -S -m32 wipe.cpp -o wipe.exe.S

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

int main(int argc, char* argv[])
{
    string s("Hello world");
    cout << "S: " << s << endl;

    char* ptr = &s[0];
    size_t size = s.length();

    if(ptr && size)
    {
        /* Needed because we can't just say to GCC, */
        /*   "give me a register that you choose".  */
        void* dummy;

        __asm__ __volatile__
        (
         "%=:\n\t"                /* generate a unique label for TOP */

#if (__WORDSIZE == 64)
         "subq $1, %2\n\t"        /* 0-based index */
#elif (__WORDSIZE == 32)
         "subl $1, %2\n\t"        /* 0-based index */
#elif (__WORDSIZE == 16)
         "subw $1, %2\n\t"        /* 0-based index */
#else
# error Unknown machine word size
#endif

         "lea (%1, %2), %0\n\t"   /* calcualte ptr[idx] */
         "movb $0, (%0)\n\t"      /* 0 -> ptr[size - 1] .. ptr[0] */
         "jnz %=b\n\t"            /* Back to TOP if non-zero */

         : "=&r" (dummy)
         :  "r" (ptr), "r" (size)
         : "0", "1", "2", "cc"
         );
    }

#if 0
    cout.setf(ios::hex, ios::basefield);
    cout.fill('0');

    for(size_t i = 0; i < s.length(); i++)
        cout << "0x" << setw(2) << ((int)s[i] & 0xff) << " ";

    cout << endl;
#endif

    cout << "S: " << s << endl;

    return 0;
}

关于c++ - 如果我移动一个值来注册和编辑它会有什么不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30008385/

相关文章:

c++ - 为什么 OSX 事件监视器不显示我启动的进程?

c# - 这里的 "this"关键字是什么意思?

c++ - 直接显示 (AMCap) - 平台 SDK

c - 如何在 cython 中调用 C 内联汇编汇编?

c - 用于求平方根的最快汇编代码。需要解释

c++ - 在不移动 C++ 的情况下从 union 访问位

c++ - 关闭 C++ 控制台应用程序时会发生什么

c - 函数地址错误

gcc - 有没有办法在gcc中使用内联asm使用在编译时求值的表达式?

c - Getrusage 内联汇编