1

I have a function in assembly called "test" a subfunction in another file called "shift" and a c function called "shiftLetter". My shiftLetter function has two parameters a char with the letter to be shifted and an integer which is the number of shifts. I am trying to send a message to my "shift" function and this function calls my c function to change each letter in this message. However, I am having trouble making this work:

test.asm

extern printf, scanf
extern shift
global _start

section .data

format3 db "%s ",0
message1:     db "This is the Message: ",10,0

original: db "Hello World.",10,0

len1:  equ  $ - original

section .text
        global  main


main:

        mov rsi, message1
        call messages


        mov rdi,original           ;message to change
        mov rsi, len1              ;size of message
        mov rbx, 3                 ;number of shifts
        call shift

        mov rsi, original
        call messages

        ret

; end main                                                                                                                                                                                                  



messages
        mov rdi,format3
        mov rdx,rsi
        mov rax,0
        call printf
        ret

shift.asm

global shift
extern shiftLetter

section .text

shift:

        mov rdx, rsi            ;rdx length of string                                                                                                                                                       

        mov rcx,0
loop:   cmp rcx, rdx
        jge done

        mov rax,  byte [rdi+rcx]    ;getting letter to change (I am sure this is wrong)
        mov r8, rbx             ;number of shifts                                                                                                                                                           
        call shiftLetter
        mov byte [rdi+rcx], rax
        inc rcx

        jmp loop

done:
        ret



Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
prxx20
  • 39
  • 5
  • 2
    What OS/compiler is this for, and have you studied its calling conventions? – Nate Eldredge May 05 '21 at 00:38
  • 2
    "I am having trouble making this work" - Q: What exactly does that mean??? Q: Are you successfully able to link your C and ASM objects? Q: What C compiler are you using? What OS are you running? SUGGESTION: Compile with -S (GCC/Linux) or /Fa (MSVS/Windows) to study what "assembly" your compiler generates. – paulsm4 May 05 '21 at 00:40
  • @paulsm4 Yes I am linking them. I think. I am sorry I am very new with assembly. I need to understand how to use my c function. Like how do I send one character at the time to my function and then when it returns how do I store this new letter in my message – prxx20 May 05 '21 at 00:59
  • Calling convention discussion [Why does Windows64 use a different calling convention from all other OSes on x86-64?](https://stackoverflow.com/q/4429398/3422102) – David C. Rankin May 05 '21 at 01:19
  • [Without any error messages or details](https://idownvotedbecau.se/itsnotworking/) about what happens for your [mcve], all we can do is close the question as unanswerable. (Or as guess of what the problem might be, see the duplicate.) – Peter Cordes May 05 '21 at 04:26

1 Answers1

1
  1. The details will vary from architecture (e.g. x86 vs. x86-64 vs. MIPS), from platform to platform (e.g. Windows vs. Linux vs MacOS) and from compiler to compiler (e.g. GCC vs. MSVS).

  2. Your best bet is to write a small C program and use the C compiler's "dump to assembly" command switch. For example:

test.c:

#include <stdio.h>

void test()
{
  char buf[10];
  buf[0] = 'A';
  buf[1] = 0;
  printf("%s\n", buf);
}

GCC "generate assembly" command line:

gcc -S -O0 x.c
ls -l x.*
-rw-r--r-- 1 root root 105 May  4 19:42 x.c
-rw-r--r-- 1 root root 598 May  4 19:43 x.s

x.s (Equivalent assembler code):

        .file   "x.c"
        .text
        .globl  test
        .type   test, @function
test:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $32, %rsp
        movq    %fs:40, %rax
        movq    %rax, -8(%rbp)
        xorl    %eax, %eax
        movb    $65, -18(%rbp)
        movb    $0, -17(%rbp)
        leaq    -18(%rbp), %rax
        movq    %rax, %rdi
        call    puts@PLT
        nop
        movq    -8(%rbp), %rax
        xorq    %fs:40, %rax
        je      .L2
        call    __stack_chk_fail@PLT
.L2:
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   test, .-test
        .ident  "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
        .section        .note.GNU-stack,"",@progbits

You can recognize this where we're initializing "buf[]":

    movb    $65, -18(%rbp)
    movb    $0, -17(%rbp)

And this, where we're calling the C runtime library puts():

    leaq    -18(%rbp), %rax
    movq    %rax, %rdi
    call    puts@PLT

You want to "experiment" with different C code, and see how it translates to assembler in your particular environment.

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • The question is using NASM syntax. Compiling with `gcc -S -O1 -masm=intel` ([How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116)) would make it at least similar syntax, although the syntax how to call a library function in a PIE-compatible way (PLT or `-fno-plt`) differ completely between GAS and NASM. ([Can't call C standard library function on 64-bit Linux from assembly (yasm) code](https://stackoverflow.com/a/52131094)). `call puts wrt ..plt` vs. `call puts@plt`. – Peter Cordes May 05 '21 at 04:22
  • Also, you can/should simplify the asm by using `gcc -fno-stack-protector -O1`. – Peter Cordes May 05 '21 at 04:23