我为Project Euler Q14编写了这两个解决方案,在汇编和C++中.它们是用于测试Collatz猜想的相同蛮力方法.装配解决方案与组装
nasm -felf64 p14.asm && gcc p14.o -o p14
C++是用.编译的
g++ p14.cpp -o p14
部件, p14.asm
section .data
    fmt db "%d", 10, 0
global main
extern printf
section .text
main:
    mov rcx, 1000000
    xor rdi, rdi        ; max i
    xor rsi, rsi        ; i
l1:
    dec rcx
    xor r10, r10        ; count
    mov rax, rcx
l2:
    test rax, 1
    jpe even
    mov rbx, 3
    mul rbx
    inc rax
    jmp c1
even:
    mov rbx, 2 …我正在阅读另一个关于两行代码效率的问题,OP说他看了代码背后的程序集,两行在程序集中是相同的.除了离题之外,我如何查看编译程序时创建的汇编代码.
我正在使用Microsoft的Visual C++,但我也想知道是否可以查看用Visual Basic编写的代码后面的程序集.
那么,如何查看用C++和Visual Basic等高级语言编写的程序背后的汇编代码?
左右移位运算符(<<和>>)已在C++中可用.但是,我无法找到如何执行循环移位或旋转操作.
如何执行"向左旋转"和"向右旋转"等操作?
在这里向右旋转两次
Initial --> 1000 0011 0100 0010
应该导致:
Final   --> 1010 0000 1101 0000
一个例子会有所帮助.
(编者注:如果旋转计数为零,许多常见的表达方式在C中旋转会受到未定义的行为的影响,或者编译为不止一个旋转机器指令.这个问题的答案应记录最佳实践.)
什么是计算(long int) ceiling(log_2(i))输入和输出为64位整数的快速方法?有符号或无符号整数的解决方案是可以接受的.我怀疑最好的方法将是一个类似于这里发现的方法,但不是尝试我自己,我想使用已经经过充分测试的东西.一般解决方案适用于所有正值.
例如,2,3,4,5,6,7,8的值为1,2,2,3,3,3,3
编辑:到目前为止,最好的路径似乎是使用任意数量的快速现有bithacks或寄存器方法计算整数/楼层日志基数2(MSB的位置),然后如果输入不是幂的话,则添加一个二.对2的幂的快速按位检查是(n&(n-1)).
编辑2:整数对数和前导零方法的一个很好的来源是亨利S.沃伦的Hacker's Delight中的第5-3和11-4节.这是我发现的最完整的治疗方法.
编辑3:这项技术看起来很有希望:https://stackoverflow.com/a/51351885/365478
我希望能够%rbp在内联asm中使用基指针寄存器().这样的玩具示例是这样的:
void Foo(int &x)
{
    asm volatile ("pushq %%rbp;"         // 'prologue'
                  "movq %%rsp, %%rbp;"   // 'prologue'
                  "subq $12, %%rsp;"     // make room
                  "movl $5, -12(%%rbp);" // some asm instruction
                  "movq %%rbp, %%rsp;"  // 'epilogue'
                  "popq %%rbp;"         // 'epilogue'
                  : : : );
    x = 5;
}
int main() 
{
    int x;
    Foo(x);
    return 0;
}
我希望,因为我使用通常的序幕/结尾函数调用方法来推送和弹出旧的%rbp,这样就可以了.但是,当我尝试在内x联asm之后访问时,它会出现故障.
GCC生成的汇编代码(略微剥离)是:
_Foo:
    pushq   %rbp
    movq    %rsp, %rbp
    movq    %rdi, -8(%rbp)
    # INLINEASM
    pushq %rbp;          // prologue
    movq %rsp, …我正在尝试实现一个旋转左侧函数,它将整数x向左旋转n位
到目前为止我有这个:
int rotateLeft(int x, int n) {
  return ((x << n) | (x >> (32 - n)));
}
我已经意识到不能为签名整数工作..任何人都有任何想法如何解决这个问题?
所以现在我试过了:
int rotateLeft(int x, int n) {
  return ((x << n) | ((x >> (32 + (~n + 1))) & 0x0f));
}
并收到错误:
错误:测试rotateLeft(-2147483648 [0x80000000],1 [0x1])失败...... ...给出15 [0xf].应为1 [0x1]
我在编译期间收到以下错误:
error: ‘asm’ undeclared (first use in this function)
 EXCHANGE( s, *(a) );
 ^
在头文件中调用宏,如下所示:
EXCHANGE( s, *(a) );
并且宏的实际定义如下:
#define EXCHANGE(R,M) asm volatile ( "xchg   %1, %0" : "+m" (M), "+r" (R) )
宏调用和定义存在于同一个头文件中.出了什么问题?
我正在使用CMAKE来构建项目,CFLAGS如下:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-field-initializers")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat=2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch-default")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith")
#-Wno-deprecated-declarations to suppress the deprecation errors with newer version of JSON-C 
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wbad-function-cast") …我试图为gcc提供内联汇编以使用单divl指令获得除法和模数.不幸的是,我在集会上并不擅长.有人可以帮我这个吗?谢谢.
为了在运行 Windows 7 pro 的英特尔核心 2 上执行一些 cmov 指令,我编写了下面的代码。它所做的只是从控制台获取一个字符串作为输入,应用一些移位操作来生成一个随机种子,然后将该种子传递给 srand,以生成一个小的伪随机数数组。然后评估伪随机数是否满足谓词函数(更任意的 bitshuffling ),并输出“*”或“_”。实验的目的是生成 cmov 指令,但是正如您在下面的反汇编中看到的那样,没有。
关于如何更改代码或 cflags 以便生成它们的任何提示?
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdlib>
bool blackBoxPredicate( const unsigned int& ubref ) {
   return ((ubref << 6) ^ (ubref >> 2) ^ (~ubref << 2)) % 15 == 0;
}
int main() {
   const unsigned int NUM_RINTS = 32;
   unsigned int randomSeed = 1;
   unsigned int popCount = 0;
   unsigned int * rintArray = new unsigned int[NUM_RINTS];
   std::string userString;
   std::cout …我一直在玩D的内联汇编程序和SSE,但发现了一些我不理解的东西.当我尝试在声明后立即添加两个float4向量时,计算是正确的.如果我把计算放在一个单独的函数中,我得到一系列的nans.
//function contents identical to code section in unittest
float4 add(float4 lhs, float4 rhs)
{
    float4 res;
    auto lhs_addr = &lhs;
    auto rhs_addr = &rhs;
    asm
    {
        mov RAX, lhs_addr;
        mov RBX, rhs_addr;
        movups XMM0, [RAX];
        movups XMM1, [RBX];
        addps XMM0, XMM1;
        movups res, XMM0;
    }
    return res;
}
unittest
{
    float4 lhs = {1, 2, 3, 4};
    float4 rhs = {4, 3, 2, 1};
    println(add(lhs, rhs)); //float4(nan, nan, nan, nan)
    //identical code starts here
    float4 res;
    auto …assembly ×5
c ×4
c++ ×4
x86 ×3
gcc ×2
optimization ×2
visual-c++ ×2
64-bit ×1
c++-faq ×1
d ×1
disassembly ×1
division ×1
i386 ×1
linux ×1
math ×1
performance ×1
red-zone ×1
rotation ×1
sse ×1
x86-64 ×1