【问题标题】:ascii char to char conversions Assembly x86?ascii char 到 char 转换程序集 x86?
【发布时间】:2019-02-20 20:00:30
【问题描述】:

我正在尝试在汇编 x86 中创建一个 atbash 密码,其中 'a's 变为 'z's,'b's 变为 'y's,依此类推。我使用的等式使得 (122-char) + 97 (ascii 值) 是 atbash 字符。

mov     al, 'c'
mov     rax, 122
mov     rcx, al
sub     rax, rcx
add     rax, 97

但是,当执行这些行时,它说操作码和操作数的组合无效。

我如何用chars 和ints 正确执行这个等式?

提前谢谢你。

【问题讨论】:

标签: assembly x86 x86-64


【解决方案1】:

如果要将字节零或符号扩展至 64 位寄存器,请分别使用 movzx ecx, almovsx rcx, al

请注意,在组装 时,您会得到“操作码和操作数的无效组合”,然后才能执行任何机器代码。那是因为您选择了一个对这些操作数没有有效编码的助记符 (mov)。


(122-char) + 97 = 122+97 - char 实现起来很简单。 122+97 = 219 仍然只有 1 个字节,因此您可以根据需要使用 8 位操作数大小。

;; input in EAX or AL
;; result in ECX or CL
mov   ecx, 'z'+'a'         ; let the assembler do the math with ASCII constants
sub   ecx, eax

或者在一个延迟更差的寄存器中:

sub   al, 'z'+'a'       ; c - 219
neg   al                ; 219 - c

【讨论】:

  • 谢谢!以下对我有用:movzx rax, al mov rdx, 122 sub rdx, rax mov rax, rdx movzx rax, al add rax, 97
  • @jikrinjuice:所有重复的零扩展都是毫无意义的。如果您最终只存储低字节,则可以只使用 32 位操作数大小(通常是最有效的)或 8 位。此外,加减运算也比 sub al, 219 / neg al 慢,就像我在回答中显示的那样。
【解决方案2】:

此行:mov rcx, al 无效,因为没有 mov 的编码,它具有 r64 目标和 r/m8 源。

这行无论如何都是多余的:

mov     al, 'c'
mov     rax, 122

al 部分寄存器是寄存器rax 的最低有效字节的别名。您将在下一行之后立即用122 覆盖'c'。如果您打算仅将'c' 复制到rcx,则可以使用movzx 指令,该指令从r/m 源零扩展到完整目标:

mov al, 'c'
movzx ecx, al ; upper 32 bits are zeroed too

幸运的是,与它的 32 位前身不同,x86_64 有更多 GPR 可供您使用(r8r15)。将其中的一些用于 12297 的算术以实现您的密码。

【讨论】:

  • movzx ecx, almovsx rcx, al 用于零扩展或符号扩展到RCX。你的回答意味着根本没有办法做这样的事情(尽管它在技术上不是错误的,因为助记符不是mov)。我不明白您为什么建议使用 xor/mov/mov 序列而不是 mov ecx, 'c'。或者当我们知道低字节以上的值为零时,为什么要使用 64 位操作数大小。
  • @PeterCordes 因为我忘记了 movzx 在那里存在一分钟
  • movzx 不存在直接来源,只有 movzx r32, r/m8movzx r32, r/m16。不幸的是,即使 x86-64 也没有为 mov r/m32, imm8 重新使用任何操作码,以便更紧凑地编码将小常量放入寄存器或内存中。像 pop ds 这样的任何一个操作码都可以重新用于此目的,但 AMD 是保守的。
  • 嗯? add r/m32, imm8add r/m32, imm32 存在单独的操作码的原因是为了提高代码密度/节省内存和 L1i 缓存中的空间。 mov-immediate 与小整数(需要填充到 32 位)不太常见 add,但编译器肯定会使用它来将立即数为零的内存归零。 (而不是对寄存器进行异或归零并存储它。)mov eax, 'c' / mov ecx, eax 将比您提出的更有效,但更大。 (5 + 2 字节与您的 2 + 3 字节)。但是你的对旧的 RAX 有错误的依赖。
猜你喜欢
  • 2013-11-20
  • 2014-10-10
  • 2015-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多