jikrinjuice
jikrinjuice

Reputation: 23

ascii char to char conversions Assembly x86?

I am trying to make an atbash cypher in assembly x86, where 'a's become 'z's, 'b's become 'y's, and so on. I'm using the equation such that (122-char) + 97 (in ascii values) is the atbash character.

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

When executing these lines however, it says there is an invalid combination of opcode and operands.

How do i perform this equation with chars and ints correctly?

Thank you in advance.

Upvotes: 2

Views: 914

Answers (2)

Govind Parmar
Govind Parmar

Reputation: 21562

This line: mov rcx, al is not valid, since there is no encoding of mov that has an r64 destination and an r/m8 source.

This line is redundant anyway:

mov     al, 'c'
mov     rax, 122

The al partial register is an alias for the least significant byte of the register rax. You are overwriting the 'c' with 122 immediately after the next line. If you intend to copy just the 'c' to rcx, you could use the movzx instruction, which zero-extends into the full destination from the r/m source:

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

Fortunately, unlike its 32-bit predecessor, x86_64 has a few more GPRs that you can use (r8 to r15). Use some of those for the arithmetic with 122 and 97 to implement your cipher.

Upvotes: 1

Peter Cordes
Peter Cordes

Reputation: 365637

If you want to zero- or sign-extend a byte into a 64-bit register, use movzx ecx, al or movsx rcx, al respectively.

Note that you were getting "invalid combination of opcode and operands" when assembling, before there's any machine code to execute. That's because you picked a mnemonic (mov) that has no valid encoding for those operands.


(122-char) + 97 = 122+97 - char which is trivial to implement. 122+97 = 219 which is still only 1 byte, so you could use 8-bit operand-size if you wanted to.

;; 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

Or in one register with worse latency:

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

Upvotes: 3

Related Questions