【问题标题】:How to decompose one 16bit number to two 8bit numbers?如何将一个 16 位数字分解为两个 8 位数字?
【发布时间】:2021-02-16 11:06:10
【问题描述】:

我在 C 中有这段代码,我想在 nasm 中,将 16 位分解为两个 8 位,我该怎么做? C

uint16_t data = 0xCAFE; // global
uint8_t result[2];
...

decompose();
printf(
  "result %d %d \n", 
  result[0], result[1]
);

ASM

 global decompose
decompose:
  enter 0,0
  movzx ax, word[data],
  movzx al, [ax]
  leave
  ret

【问题讨论】:

  • 您的汇编代码永远不会写入result。此外,没有movzx r16, r/m16。只需使用普通的mov
  • 取决于哪个字节应该是 MS 和 LS,或者它是否应该与 CPU 字节序相同。无论如何,只需研究按位运算符,或者在网站上找到这个问题的众多重复项中的任何一个。
  • AX 已经是 2 个独立的寄存器,AH 和 AL。在movzx eax, word [data] 之后,您就可以有效地将 16 位加载到 EAX 中(AX 中的低 16 位)。或将 AX 存储到 [result],如果你想要它,就像 memcpy(result, &data, 2);。字节只是字节,一次复制多个并不特殊。
  • 或者更好的是,将result 设为data 的别名,或与它联合的一部分,这样您就不必复制了,这只是访问相同底层字节的另一种C 方式.

标签: c assembly x86 x86-64 nasm


【解决方案1】:

首先:创建具有全局副作用的函数是非常糟糕的设计,例如获取他们的论点或通过全局变量传递他们的结果。
第二:绝对没有理由对此使用汇编。如果您将结果传递给类似的慢速打印例程,则尤其如此。

如果你真的想拥有这样的功能,我建议引入小的内联函数

static inline uint8_t u16High(uint16_t v){ return (uint8_t)(v >> 8); }
static inline uint8_t u16Low (uint16_t v){ return (uint8_t)(v);      }

另一个(在我看来很难看)选项是:

static inline uint8_t* u16decompose(uint16_t* v){ return (uint8_t*)v; }

但请注意:这仅适用于uint8_t*,您不能将其用于将uint32_t 分解为uint16_t,因为这违反了严格的别名规则。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 2017-04-19
    • 1970-01-01
    • 2013-02-13
    相关资源
    最近更新 更多