【问题标题】:Convert a decimal string to a signed 2's complement binary integer将十进制字符串转换为有符号 2 的补码二进制整数
【发布时间】:2019-12-28 13:49:30
【问题描述】:

我只是想知道将十进制整数(由用户输入)转换为内存中 2 的补码表示的代码是什么。

示例:用户输入 1234 作为小数。我想在 AX 中存储 04D2(二进制 2 的补码表示)(因为我只允许使用字长字符串)

我使用的是 80x86 架构。

【问题讨论】:

  • 嗯,04d2 不是二进制补码。它只是十六进制的数字 1234。您是否尝试将字符串解析为整数?
  • 好吧,我的最终目标是从用户那里得到一个 16 位数字,将其转换为 2 的补码,然后找到它的八进制表示。我
  • 您还需要处理负整数,还是只处理正整数?
  • 负整数也是如此。我举了两个例子。 1234 的八进制表示是 004 322。-1 的八进制表示是 377 377。我了解他们为什么以及如何获得八进制表示,我只需要中间步骤说明他们如何在代码中从 1234 获得 04D2。
  • 伪代码,适用于带有 ASCII 字符集的 kbd。你要弄清楚积极或消极的逻辑,因为它在这里会变得太局促。 :) result = 0; while( (c = kbdRead) != '\n') { result *= 10; result += c - '0' (注​​意:我的头顶......)还要注意 2 的补码中的负数具有 MSB 集。

标签: assembly input x86


【解决方案1】:

将一串数字转换为整数非常简单:一次读取一个数字,然后将其转换为十进制数(通常通过从中减去“0”)。您将现有值乘以十,然后加上当前数字的值。

处理负数只会增加一点难度。大多数人这样做是通过保留一个标志来表示如果它以'-'开头的数字是负数。然后,当他们转换数字时,如果设置了该标志,他们就会否定。

但是,这样做有一个问题:转换最大的负数需要一些额外的工作,因为(在 2 的补码中)最大的负数比您可以表示为正数的幅度更大(不使用更多位) .例如,16 位 2 的补码范围从 -32768 到 +32767,但您需要(至少)17 位或无符号 16 位数字来表示 +32768。

编辑:将十进制数字转换为整数后,您需要将整数转换为十六进制数字才能以十六进制显示。这种转换要容易一些。您反复除以 16,余数成为下一个十六进制数字。您通常会使用像“0123456789abcdef”这样的表格,并使用剩余部分来索引表格以获取要显示的数字。您重复除法并使用余数,直到您的股息为零。一个技巧是,这会以 reverse 顺序(从最低到最高有效)生成数字,因此您通常将它们放入缓冲区中,从缓冲区的末尾开始并朝着开头前进.

【讨论】:

  • 我想我要问的是当用户输入一个数字时,我怎样才能看到它的十六进制值。
  • @cj1098:您必须将十进制数字转换为整数。然后你必须从整数转换为十六进制数字。
  • @cj1098:对于ASCII十进制数字的无符号字符串->二进制整数(没有前导--处理),请参阅NASM Assembly convert input to integer?total = total*10 + new_digit算法。 (另见the x86 tag wiki 的“多位数字”部分)。要将寄存器值(二进制整数)视为十六进制,请使用调试器以十六进制显示。或者使用计算器。
【解决方案2】:

它需要注意位,然后加 1……但前提是你知道它是否为正。 如果它的负数你必须取1,那么不是它,相反的操作。应该是2个周期。

【讨论】:

  • neg eax 是具有 1 个周期延迟的单 uop 指令(它的工作原理是从 0 中减去,这与 not eax; inc eax 相同,因为 x86 是 2 的补码 ISA)。如果您想要 2 的补码 否定,请使用它。但这实际上并不是这个问题要问的:它问的是如何将(有符号的)十进制数字字符串转换为有符号整数。
  • re: 循环:请参阅agner.org/optimize,了解现代 x86 微架构上的性能如何工作。延迟和吞吐量是不同的东西。也可以stackoverflow.com/tags/x86/info 获取更多链接。
猜你喜欢
  • 2020-11-26
  • 2021-07-13
  • 2014-05-21
  • 2011-09-03
  • 2020-04-29
  • 1970-01-01
  • 2016-08-31
  • 2016-07-16
  • 2021-01-23
相关资源
最近更新 更多