0

I have a c funtion that receives a character and an integer as parameter and shift that character using the integer. So let's say the character is "a" and the integer is 2 it will return "c". What I need to do is to get the string and the number of shifts from the user in assembly. Then call my function and return the encrypted word. So if the word is Love and the number of shifts is 2 the word will become Nqxg.

I am having the worst time doing this. No idea what to do I have tried so many things already.

When I run just come the first Letter. So at least something is working. I am sure is about the size, I am very new to assembly and still trying to understand how the register work. I also don't know how to append my characters to my string

Can anyone please try to fix my shift subroutine? Thank you

That's what I have:

extern printf, scanf
extern encrypt


global _start

section .data
format db '%ld',0
format3 db "%s ",0

message1:     db "1. Input New Message",10,0
message2:     db "Enter a number of shift:",10,0

section .bss
getMessage:     resq 1
shiftNum          resq 1
encrypted          resq 1

len:  equ  $ - getMessage
base: equ getMessage - 4


section .text
        global  main


main:

        mov rdx, message1
        call print

        call scanMessage

        mov rdx, message2
        call print

        call scanChoice

        mov rdx, getMessage
        call print

        mov r8, getMessage
        mov rbx, [shiftNum]
        mov rdx, len
        call shift

        mov rdx, encrypted
        call print

        ret

; end main     

scanChoice:                     ;getting the year from user                                                                                                                                                 
   mov rdi, format
        mov rsi, shiftNum
        mov rax, 0              ;no xmm registers                                                                                                                                                           
        call scanf              ;calling c function to get input from user                                                                                                                                  
        ret

scanMessage:
        mov rax, 0
        mov rdi, 0
        mov rsi, getMessage
        mov rdx, len
        syscall
        ret                                                                    \

print:
        mov rdi,format3
        mov rsi,rdx
        mov rax,0
        call printf
        ret

shift:
        mov rcx, 0
loop:   cmp rcx, rdx            ;comparing string length with rcx                                                                                                                                           
        jge done
        mov rdi, [r8+ rcx*4]
        mov rsi, rbx            ;number of shifts                                                                                                                                                           
        call encrypt
        mov [encrypted+rcx*4], rax ;appending to string                                                                                                                                                     
        inc rcx
        jmp loop
done:
        ret
                

My output:

1. Input New Message

Hello

 Enter a number of shift:

 4

Hello

 L

->that's what is coming instead of Lipps which would be each letter from Hello shifted 4 times

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
prxx20
  • 39
  • 5
  • Yes, the len handling is off. You reserved a QWORD for `getMessage` string (so at most 8 bytes). I don't know if that's intentional but the `len equ $-x` trick works only if you put if after the string (that BTW has a fixed len, so you don't really need it). But more than that, you are reading QWORDs with a 4-byte step out of your string. That's probably why only the first character is shifted and printed (the rest is clobbered/zeroed). – Margaret Bloom May 09 '21 at 17:17
  • Use a debugger to single-step your code and look at register values. `mov rdi, [r8+ rcx*4]` loads 8 bytes, with an index scaled by 4. Very likely you want something like `movzx edi, byte [r8 + rcx]` before the call, and `mov [r8+rcx], al` to store the byte result. But note that RCX and R8 are both call-clobbered registers: you can't assume their values survive across a `call` to a compiled C function. [What registers are preserved through a linux x86-64 function call](https://stackoverflow.com/q/18024672) – Peter Cordes May 09 '21 at 17:22
  • @MargaretBloom so what do I have to use to reserve the space for the string? Should be resb? Also How do I append the characters to my append variable and how do loop to go to every character if my length string is not working? – prxx20 May 09 '21 at 17:36
  • @PeterCordes thank you, but I do not understand what call-clobbered are. What should I use then? – prxx20 May 09 '21 at 17:36
  • [What registers are preserved through a linux x86-64 function call](https://stackoverflow.com/q/18024672) shows which registers will / won't (necessarily) survive across a function call. See [What are callee and caller saved registers?](https://stackoverflow.com/a/56178078) if you didn't understand the terminology. – Peter Cordes May 09 '21 at 17:56

0 Answers0