【问题标题】:function that adds 16-bit variables添加 16 位变量的函数
【发布时间】:2020-12-03 08:37:46
【问题描述】:

我正在编写我的第一个模拟器(Intel 8086 微处理器)。

我被困住了,因为我必须编写一个将 16 位变量加在一起的函数。下面是我要写的函数原型:

uint16_t add(uint16_t reg, uint16_t operand);

例如,如果我们执行:

add(5, 3)

函数应该像这样进行计算:

              111
  0000000000000101 (= 5)
+ 0000000000000011 (= 3)
  ----------------
              1000 (= 8)

然后返回 8。

要编写这个函数,我需要找到一种方法来访问这两个变量的每一位,然后能够将它们加在一起并将它们放在第三个变量中。

这在 C 中是否可行,如果可以,有人可以告诉我吗?

非常感谢您的回答。

【问题讨论】:

  • 嗯。 reg + operand 就是这样做的……
  • 是的,但它不会完全按照我想要的方式运行。例如,如果发生溢出,运算符 + 将发生段错误。但是使用我的添加功能,我只是要设置 CF 标志。
  • 不,操作员+ 永远不会出现段错误。您可以轻松检查“溢出”(这实际上是无符号整数的明确定义的“环绕”)并设置您的 CF。如果您将临时结果变量设为uint32_t,那么您可以轻松检查它是否超出uint16_t 的范围。
  • 所以这是正常的加法,但有进位。在这种情况下,CF 是什么,一些全局变量?
  • 我有一个全局变量uint16_t registers[]registers[10] = FLAGS。 FLAGS uint16_t 变量的第 0 位是进位。

标签: c emulation add x86-16 16-bit


【解决方案1】:

假设是 32 位计算机,这很简单:

#include <stdint.h>
#include <stdio.h>

_Bool carry;

uint16_t add (uint16_t reg, uint16_t operand)
{
  carry = (reg + operand) & 0xFFFF0000u;
  return reg + operand;
}

int main (void)
{
  int sum = add(65535, 1);
  printf("%d, CF:%d\n", sum, (int)carry);
}

reg + operand 将提升为 32 位 int,如果加法超过 16 位,布尔标志将设置为 1。

【讨论】:

  • 是的,但是当我编写模拟器时,这并不重要。结果必须是 16 位。
  • 啊,好的。我的印象是它需要在 8086 上运行
  • @EugeneSh。然后它将使用 32 位类型的软件库,就像 8 位和 16 位微控制器一样。因此,如果您使用 32 位数字而没有硬件支持,生成的机器代码会变得非常臃肿。
  • @Lundin 我的意思是 carry = (reg + operand) &amp; 0xFFFF0000u 行不适用于 16 位整数。但显然它很可能不会成为问题,因为它将在现代 PC 上运行。
【解决方案2】:

你非常大致需要这样的东西:

#include <stdio.h>
#include <stdint.h>

int carry = 0;

uint16_t add(uint16_t reg, uint16_t operand)
{
  uint32_t result = (unint32_t)reg + operand;

  carry = 0;
  if (result > 0xffff)
    carry = 1;

  return result &= 0xffff;
}


int main()
{
  uint16_t r1, r2, r3;

  r1 = 0x10;
  r2 = 0x1000;
  r3 = add(r1, r2);
  printf("r3 = %04x, carry = %d\n", r3, carry);

  r1 = 0x11;
  r2 = 0xffff;
  r3 = add(r1, r2);
  printf("r3 = %04x, carry = %d\n", r3, carry);
}

根据您的需要调整它。

【讨论】:

  • 感谢所有花时间回答我问题的人!确实,我没有想过那样做,这是一个非常好的主意。好吧,这只会在可以存储 32 位变量的机器上运行(但毕竟没有很多)。谢谢
  • @NathanCasabieille 标准 C 要求目标系统上存在 32 位类型,因为它必须支持 long 类型。
  • 在这种情况下没有问题,谢谢你的信息!
【解决方案3】:

如果要获取第n位(第0位是最低位,第16位是最高位),可以这样做

uint8_t bit = (num >> n) & 1;

它的作用是右移数字n 位,所以你想要的位是最低有效位,然后它会做一个位掩码来只得到那个位。

【讨论】:

  • 这是在回答 XY 问题的“Y”部分。
猜你喜欢
  • 2013-05-14
  • 2022-09-24
  • 1970-01-01
  • 2023-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 2021-02-20
相关资源
最近更新 更多