Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly ascii字符到字符转换程序集x86?_Assembly_X86_X86 64 - Fatal编程技术网

Assembly ascii字符到字符转换程序集x86?

Assembly ascii字符到字符转换程序集x86?,assembly,x86,x86-64,Assembly,X86,X86 64,我试图在x86汇编中制作一个atbash密码,其中“a”变成“z”,b变成“y”,等等。我使用的公式是,ascii值中的122字符+97是atbash字符 mov al, 'c' mov rax, 122 mov rcx, al sub rax, rcx add rax, 97 然而,当执行这些行时,它表示操作码和操作数的组合无效 如何正确地使用chars和int来执行此等式 提前感谢。这一行:mov rcx,al无效,因为没有具有r64目标和r/m8源

我试图在x86汇编中制作一个atbash密码,其中“a”变成“z”,b变成“y”,等等。我使用的公式是,ascii值中的122字符+97是atbash字符

mov     al, 'c'
mov     rax, 122
mov     rcx, al
sub     rax, rcx
add     rax, 97
然而,当执行这些行时,它表示操作码和操作数的组合无效

如何正确地使用chars和int来执行此等式

提前感谢。

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

这条线是多余的:

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


幸运的是,与它的32位前身不同,x86_64还有一些GPRs,您可以使用r8到r15。将其中一些用于122和97的算术运算,以实现您的密码。

如果您想将字节归零或符号扩展到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

上概述了mov的有效操作数。没有r64,r/M8有movzx ecx,al或movsx rcx,al到零延伸或符号延伸到rcx。你的回答意味着根本没有办法做这样的事情,尽管从技术上讲这并没有错,因为助记符不是mov。我不明白你为什么建议使用xor/mov/mov序列而不是mov ecx,‘c’。或者,当我们知道一个值在低字节以上为零时,为什么要使用64位操作数大小。@彼得考德斯,因为我忘记了movzx存在了一分钟,而movzx不存在直接源,只有movzx r32,r/m8和movzx r32,r/m16。不幸的是,即使是x86-64也没有为mov r/m32、imm8重新使用任何操作码,以便在寄存器或内存中放入小常量,从而实现更紧凑的编码。任何一款像pop ds这样的操作码都可以被重新调整用途,但AMD是保守的,嗯?add r/m32、imm8和add r/m32、imm32都有单独的操作码,其原因是为了增加代码密度/节省内存和L1i缓存中的空间。带有需要填充到32位的小整数的mov immediate是不太常见的加法,但编译器肯定会使用它来将内存的immediate设置为零。而不是对寄存器进行异或归零并存储。mov-eax,'c'/mov-ecx,eax将比您建议的更有效,但更大。5+2字节与您的2+3字节。但是你对旧RAX的依赖是错误的。谢谢!以下内容对我有用: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,就像我在回答中所显示的那样。
sub   al, 'z'+'a'       ; c - 219
neg   al                ; 219 - c