使用 x86 mov 指令实现 C 转换

Achieve C casting using x86 mov instructions

我正在看书 "Computer Systems: A Programmer's Perspective"。现在我不确定我是否理解何时使用不同的 mov 指令。这是练习:

Practice Problem 3.4

Assume variables v and p declared with types

src_t v;

dest_t *p;

where src_t and dest_t are data types declared with typedef. We wish to use the appropriate data movement instruction to implement the operation

*p = (dest_t) v;

where v is stored in the appropriately named portion of register %eax (i.e., %eax, %ax, or %al), while pointer p is stored in register %edx.

For the following combinations of src_t and dest_t, write a line of assembly code that does the appropriate transfer. Recall that when performing a cast that involves both a size change and a change of “signedness” in C, the operation should change the signedness first (Section 2.2.6).

我正在对照 this blog post 检查我的解决方案,但我不确定我是否理解问题 3:

src_t       dest_t      My Solution              Blog's Solution

char        unsigned    movzbl %al, (%edx)     movsbl %al, (%edx)

第 3 条:我使用 movzbl,而博客作者使用 movsbl。在这种情况下,我不明白 movzbl 与 movsbl 的推理......如果 char 是负数,你最终会得到一个错误的数字,任何人都可以澄清为什么 movsbl 是正确的选择吗?

Recall that when performing a cast that involves both a size change and a change of “signedness” in C, the operation should change the signedness first (Section 2.2.6).

除非我看错了,否则这句话似乎与他给出的正确答案相冲突。

该规则意味着,从有符号字符开始:

  • 符号字符
  • -> 无符号字符
  • -> 无符号整数

所以大小转换是从 unsigned char 到 unsigned int,所以 movz 是合适的。大概规则是错误的(与 C 实际指定的不匹配),movs 确实是 C 编译器会使用的规则。

Jester的评论说-1 char值的unsigned int值必须是0xffffffff,所以看起来像练习题最后一句关于转换signedness和size的顺序是问题所在。