C或C中乘法和除法的较高部分?

当我在程序集中乘以一对4字节整数时,结果的下半部分在EAX中,EDX中的较高部分.如果我在C或C中,我想获得更高的部分,是否可能没有使用内联汇编?

以同样的方式可以得到EAX的整数除法结果和EDX的模数结果,而不会重复C或C的划分?我实际上只知道做第一个a / b,然后是一个%b,而在汇编器中,两个结果都是在同一个操作中给出的.

解决方法

你可以很容易地用C这样做:
#include <stdint.h>

uint32_t a,b;  // input
uint64_t val = (uint64_t)a * b;
uint32_t high = val >> 32,low = val;

把它留给编译器来生成最好的代码.现代优化器真的很好.手编组装通常看起来更好,但表现更差.

由Pete Becker评论,上述依赖于uint32_t和uint64_t类型的可用性.如果您坚持使用硬盘可移植性(例如您在DS9K上进行编程),则可以使用在C99下始终可用的类型uint_least32_t和uint_least64_t或uint_fast32_t和uint_fast64_t,但是您需要一个额外的掩码,如果不需要:

#include <stdint.h>

uint_fast32_t a,b;  // input
uint_fast64_t val = (uint_fast64_t)a * b;
uint_fast32_t high = (val >> 32) & 0xFFFFFFFF,low = val & 0xFFFFFFFF;

关于划分,您可以使用C99库函数div,ldiv或lldiv在一次调用中执行带符号除法和余数操作.如果可能,在特定操作数类型的目标架构上,分割/模组合将在一个操作中实现.

编写两个表达式可能会更有效,并依靠编译器检测模式并生成使用单个IDIV操作码的代码

struct divmod_t { int quo,rem; };
struct divmod_t divmod(int num,int denom) {
    struct divmod_t r = { num / denom,num % denom };
    return r;
}

测试在Matt Godbolt’s compiler explorer显示clang和gcc生成一个单一的idiv指令这个代码在-O3.

你可以将其中一个分为一个乘法:

struct divmod_t { int quo,rem; };
struct divmod_t divmod2(int num,int denom) {
    struct divmod_t r;
    r.quo = num / denom;
    r.rem = num - r.quo * denom;
    return r;
}

请注意,上述功能不会检查潜在的溢出,这会导致未定义的行为.如果denom = 0,并且如果num = INT_MIN和denom = -1,则发生溢出.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...