我想创建一个宏或函数1 mask(n),给定一个数字n返回一个无符号整数,其n最低有效位设置.虽然这似乎应该是一个基本的原语,经过大量讨论的实现有效编译 - 似乎并非如此.
当然,各种实现对于原始整数类型可能具有不同的大小unsigned int,因此,为了具体起见,我们假设我们正在讨论uint64_t具体返回,尽管当然可接受的解决方案对于任何无符号整数类型都有效(具有不同的定义).特别是,当返回的类型等于或小于平台的原始宽度时,解决方案应该是高效的.
重要的是,这必须适用于所有人n[0,64].尤其是mask(0) == 0和mask(64) == (uint64_t)-1.许多"明显的"解决方案不适用于这两种情况之一.
最重要的标准是正确性:只有不依赖于未定义行为的正确解决方案才是有趣的.
第二个最重要的标准是性能:理想情况下,成语应该编译成大致最有效的平台特定方式,以便在通用平台上执行此操作.
在性能名称中牺牲简单性的解决方案,例如,在不同平台上使用不同的实现,是很好的.
1最常见的情况是一个函数,但理想情况下它也可以作为宏工作,而不必多次重新评估它的任何参数.
我试图将这个C函数转换为Python;
typedef unsigned long var;
/* Bit rotate rightwards */
var ror(var v,unsigned int bits) {
return (v>>bits)|(v<<(8*sizeof(var)-bits));
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试过谷歌搜索一些解决方案,但我似乎无法让他们中的任何一个给出与此处相同的结果.
这是我从另一个程序中找到的一个解决方案;
def mask1(n):
"""Return a bitmask of length n (suitable for masking against an
int to coerce the size to a given length)
"""
if n >= 0:
return 2**n - 1
else:
return 0
def ror(n, rotations=1, width=8):
"""Return a given number of bitwise right rotations of an integer n,
for a given bit field width.
"""
rotations %= …Run Code Online (Sandbox Code Playgroud) 我试图用C++编写一些关于"按位旋转"的代码,我想通过左边的shif来做这个.我不知道如何编写代码,但我在"维基百科"中找到了一些像这样的代码.
unsigned int rotl(unsigned int value, int shift) {
return (value << shift) | (value >> (sizeof(value) * CHAR_BIT - shift));
}
Run Code Online (Sandbox Code Playgroud)
然后我试着让它工作,但是这段代码没有给出我期望的输出.防爆.我有数字unsigned int 12,在二进制1100中,当我想用左shif按上面的代码进行按位旋转时,输出是和unsigned int 24(11000),它必须给出输出unsigned int 9,因为如果我进行按位旋转(左shif),第一个MSB位现在必须是第一位,所有其他位必须向左移动一位.
你能帮助理解那是什么问题吗?或者我做错了什么.
谢谢.
我知道StackOverflow不是为了向其他人询问代码,而是让我说话.
我正在尝试在CUDA C++设备代码中实现一些AES函数.在尝试实现左侧按字节旋转运算符时,我感到不安的是看到没有原生的SIMD内向.所以我开始了一个天真的实现,但......它是巨大的,虽然我还没有尝试过,但由于昂贵的拆包/打包,它不会很快......所以,有什么意思吗每字节位旋转操作至少有些效率?
如果您不想看看,这是代码.
__inline__ __device__ uint32_t per_byte_bit_left_rotate(uint32_t input, uint8_t amount) {
return ((((input & 0xFF) >> 0) << amount) | (((input & 0xFF) >> 0) >> 7) & ~0x100) << 0 |
((((input & 0xFF00) >> 8) << amount) | ((input & 0xFF00 >> 8) >> 7) & ~0x100) << 8 |
((((input & 0xFF0000) >> 16) << amount) | ((input & 0xFF0000 >> 16) >> 7) & ~0x100) << 16 |
((((input & 0xFF000000) >> 24) …Run Code Online (Sandbox Code Playgroud) 在Xeno Kovah在OpenSecurityTraining 上主持的x86 程序集介绍的第一天作业中,他指定:
我们现在知道的说明(24)
NOP PUSH/POP CALL/RET MOV/LEA ADD/SUB JMP/Jcc CMP/TEST AND/OR/XOR/NOT SHR/SHL IMUL/DIV REP STOS,REP MOV LEAVE
编写一个程序来查找我们尚未涵盖的指令,并在明天报告该指令。
他进一步断言这个任务是,
SAL/SAR MUL/IDIV变体IMUL/DIV也不要指望是否可以找到 GCC 当前输出的 x86 汇编指令列表,而不是objdump随机执行并审核它们然后创建源代码?
这个问题的基础似乎是实际使用的指令的一个非常小的子集,人们需要知道逆向工程(这是课程的重点)。Xeno 似乎试图找到一种有趣的、有指导意义的方式来说明这一点,
我认为知道大约 20-30(不包括变化)就足够了,你很少会检查手册
虽然我欢迎大家加入我在 OpenSecurityTraining 的这个很棒的课程,但问题是我提出的从 GCC 中找出它的方法(如果可能的话)。不是,让人们真正完成 Xeno 的任务。;)
#include <stdio.h>
#include <iostream>
#include <string>
#include <chrono>
#include <memory>
#include <cstdlib>
#include <cstdint>
#include <cstring>
#include <immintrin.h>
using namespace std;
const int p[9] = {1, 10, 100,
1000, 10000, 100000,
1000000, 10000000, 100000000};
class MyTimer {
private:
std::chrono::time_point<std::chrono::steady_clock> starter;
public:
void startCounter() {
starter = std::chrono::steady_clock::now();
}
int64_t getCounterNs() {
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - starter).count();
}
};
int convert1(const char *a) {
int res = 0;
for (int i=0; i<9; i++) res = res * 10 + a[i] - 48; …Run Code Online (Sandbox Code Playgroud) 我要实现一个向左和向右执行循环旋转的函数.所以我为这两个操作写了同样的东西.例如,如果你正在旋转左边1010变成0101.这是对的吗?
unsigned char rotl(unsigned char c) {
int w;
unsigned char s = c;
for (w = 7; w >= 0; w--) {
int b = (int)getBit(c, w);//
if (b == 0) {
s = clearBit(s, 7 - w);
} else if (b == 1) {
s = setBit(s, 7 - w);
}
}
return s;
}
unsigned char getBit(unsigned char c, int n) {
return c = (c & (1 << n)) >> n;
}
unsigned char setBit(unsigned char …Run Code Online (Sandbox Code Playgroud) 给定一个xmm包含两个四字(即两个 64 位整数)的 128 位寄存器:
???????????????????????????????????????
xmm0 ? ffeeddccbbaa9988 ? 7766554433221100 ?
???????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
如何对单个四字执行旋转?例如:
prorqw xmm0, 32 // rotate right packed quadwords
???????????????????????????????????????
xmm0 ? bbaa9988ffeeddcc ? 3322110077665544 ?
???????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
我知道 SSE2 提供:
PSHUFW:随机打包字(16 位)PSHUFD: shuffle 打包双字(32 位)虽然我不知道指令是做什么的,也没有四字(64 位)版本。
你将如何执行ROR的的xmm寄存器-假设打包数据等大小?
按 16 位旋转右压缩双字:
?????????????????????????????????????????????
xmm0 ? ffeeddcc ? bbaa9988 ? 77665544 ? 33221100 ?
?????????????????????????????????????????????
? …Run Code Online (Sandbox Code Playgroud)我正在尝试在不使用内联汇编的情况下有效地实现SHLD和SHRD说明x86。
uint32_t shld_UB_on_0(uint32_t a, uint32_t b, uint32_t c) {
return a << c | b >> 32 - c;
}
Run Code Online (Sandbox Code Playgroud)
似乎有效,但当c == 0第二个移位的操作数变为时会调用未定义的行为32。SHLD第三个操作数的实际指令0被明确定义为不执行任何操作。(https://www.felixcloutier.com/x86/shld)
uint32_t shld_broken_on_0(uint32_t a, uint32_t b, uint32_t c) {
return a << c | b >> (-c & 31);
}
Run Code Online (Sandbox Code Playgroud)
不会调用未定义的行为,但当c == 0结果是a | b而不是a.
uint32_t shld_safe(uint32_t a, uint32_t b, uint32_t c) {
if (c == …Run Code Online (Sandbox Code Playgroud) 如何反转和旋转十六进制数并使用按位运算符返回C中的数字?
例如:
0xabcd -> 0xdcba
0xabcd -> 0xdabc
Run Code Online (Sandbox Code Playgroud)