为何x86汇编中RDRAND生成的被除数会导致DIV指令抛出异常?
RDRAND配合DIV触发除法异常的原因与解决办法
问题本质:对DIV指令的行为理解偏差
你碰到的「Floating point exception (core dumped)」其实是除法异常(#DE),核心问题出在DIV cl的执行逻辑上:
DIV cl是无符号8位除法指令,CPU会把**整个AX寄存器(16位)**当作被除数,用CL里的8位数值做除数。- 这个指令要求除法的商必须能放进AL寄存器(8位,最大值255)。如果商超过255,直接触发#DE异常。
- 简单说:只要AH里的值≥CL的值,AX÷CL的商肯定大于255,必然触发异常。
为什么固定值42没问题?
当你用mov ax,42时,AX的值是0x002A,AH是0,明显小于CL=4,所以商是10,完全能放进AL,自然不会报错。
RDRAND的锅?不,是用法错了
rdrand ax生成的是16位随机数,AH的值是随机的,有98%以上的概率会出现AH≥4的情况,一旦出现就触发异常——这和随机数能不能被4整除没关系,哪怕随机数是4的倍数,只要AH≥4,照样炸。
解决办法
根据你的需求,两种方式任选:
- 直接生成8位随机数,用AL当被除数:
rdrand al; mov cl,4; div cl; mov %0, ah; - 非要用16位随机数的话,先把AH清零,只取低8位来运算:
rdrand ax; xor ah, ah; ; 清空AH,确保被除数是8位无符号数 mov cl,4; div cl; mov %0, ah;
另外提一句:你注释掉的RDRAND重试逻辑(jnc try_again)建议恢复,虽然不是这次报错的原因,但RDRAND有极低概率生成失败,不加的话可能拿到无效值。
内容的提问来源于stack exchange,提问作者Mark Nelson
相关产品推荐
相关产品推荐

