我正在尝试在程序集x86中创建一个atbash密码,其中'a'
变成'z'
,'b'
变成'y'
,依此类推。我使用的方程式是(122-char)+ 97(按ascii值)是atbash字符。
mov al, 'c'
mov rax, 122
mov rcx, al
sub rax, rcx
add rax, 97
但是在执行这些行时,它表示操作码和操作数的组合无效。
我如何正确地使用char
和int
s来执行此方程?
谢谢。
答案 0 :(得分:3)
如果要将字节零扩展或符号扩展到64位寄存器中,请分别使用movzx ecx, al
或movsx 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
答案 1 :(得分:1)
此行:mov rcx, al
无效,因为没有mov
目的地为r64
的{{1}}的编码。
反正这行是多余的:
r/m8
mov al, 'c'
mov rax, 122
部分寄存器是寄存器al
的最低有效字节的别名。您将在下一行之后立即用rax
覆盖'c'
。如果您打算仅将122
复制到'c'
,则可以使用movzx
指令,该指令从rcx
源零扩展到完整目标:
r/m
幸运的是,与32位前任产品不同,x86_64具有更多可以使用的GPR(mov al, 'c'
movzx ecx, al ; upper 32 bits are zeroed too
至r8
)。将其中一些用于r15
和122
的算术以实现密码。