我有这个函数(RDRand-由David Heffernan编写),它可以在32位中正常工作,但在64位中失败:
function TryRdRand(out Value: Cardinal): Boolean;
{$IF defined(CPU64BITS)}
asm .noframe
{$else}
asm
{$ifend}
db $0f
db $c7
db $f1
jc @success
xor eax,eax
ret
@success:
mov [eax],ecx
mov eax,1
end;
函数的文档在这里:https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
特别是上面写着:
本质上,开发人员使用单个操作数调用此指令:存储随机值的目标寄存器。请注意,该寄存器必须是通用寄存器,寄存器的大小(16、32或64位)将决定返回的随机值的大小。
调用RDRAND指令后,调用者必须检查进位标志(CF)以确定在执行RDRAND指令时随机值是否可用。如表3所示,值1表示随机值可用并放置在调用中提供的目标寄存器中。值0表示随机值不可用。在当前架构中,作为此条件的副作用,目标寄存器也将被归零。
我对ASM的了解很低,我错过了什么?
此外,我不太理解此说明:
...
xor eax,eax
ret
...
它到底是做什么的?
如果您想要一个执行完全相同的函数,那么我认为如下所示:
function TryRdRand(out Value: Cardinal): Boolean;
asm
{$if defined(WIN64)}
.noframe
// rdrand eax
db $0f
db $c7
db $f0
jnc @fail
mov [rcx],eax
{$elseif defined(WIN32)}
// rdrand ecx
db $0f
db $c7
db $f1
jnc @fail
mov [eax],ecx
{$else}
{$Message Fatal 'TryRdRand not implemented for this platform'}
{$endif}
mov eax,1
ret
@fail:
xor eax,eax
end;
Peter Cordes提出的在ash中实现重试循环的建议在我看来是明智的。我不会在这里尝试实现它,因为我认为它有点超出了你的问题范围。
此外,Peter指出,在x64中,您可以读取具有REX. W=1前缀的64位随机值。这看起来像这样:
function TryRdRand(out Value: NativeUInt): Boolean;
asm
{$if defined(WIN64)}
.noframe
// rdrand rax
db $48 // REX.W = 1
db $0f
db $c7
db $f0
jnc @fail
mov [rcx],rax
{$elseif defined(WIN32)}
// rdrand ecx
db $0f
db $c7
db $f1
jnc @fail
mov [eax],ecx
{$else}
{$Message Fatal 'TryRdRand not implemented for this platform'}
{$endif}
mov eax,1
ret
@fail:
xor eax,eax
end;
概要 <transform transVar> ... </transform> or <transform transVar name1=value1 name2=value2 ... nameN=valueN> ... </transform> 这里: transVar: 要来转换的表达式 name1, name2,... nameN: 参数的名称。文字值,不是表达式 value1
我正在尝试理解OpenSSL中使用的x86汇编函数,以使用CPU的RDRAND指令获取随机字节。这是函数体: 我不知道cmp和cmobile指令的用途。我不是x86汇编程序员,但从我看过的参考文献中可以看出,我对它的作用的理解是: 因此,如果rdrand失败,rax只能为0(进位标志是明确的),并且只有当1)rdrand成功(进位设置)并在rax中放入非零数字,或2)ecx中的重试计数器已减为0时
问题内容: 的在系统调用 包在Golang返回类型,而底层系统调用实际上返回一个指针。它是如何做到的? 更具体地说,在Golang开发人员的此程序包中,该函数仅返回一个指针。如何将其转换为字节片,就像在Unix软件包中一样? 问题答案: 使用该包,您可以在未导出类型的Mmap方法中执行相同的操作: 这是一个操场的例子。
5、类型转换指令 在作有符号除法时,有时需要把短位数的被除数转换成位数更长的数据类型。比如,要用BL中的数据去除AL,但根据除法指令的规定:除数是8位,则被除数必须是AX,于是就涉及到AH的取值问题。 为了方便说明,假设:(AH)=1H,(AL)=90H=-112D,(BL)=10H。 1)、在作除法运算前,必须处理AH的原有内容 假设在作除法时,不管AH中的值,这时,(AH、AL)/BL的商是1
问题内容: 如果我有: 上面是固定的-我不能更改foo或bar。另外,baz必须在bar内转换回foo struct指针。如何将&foo {}强制转换为interface {},以便在调用bar时可以将其用作参数? 问题答案: 要打开到一个很简单: 为了返回到,您可以执行 类型断言 : 或 类型开关 (类似,但可以是多种类型则很有用):
当使用来自外部库的函数时,“任意”取消引用指向const引用的指针是否安全? 这样做是否普遍安全/明智 更重要的是,除了C语言中“不赞成”的原始指针之外,使用常量指针真的有充分的理由这样做吗?