0

I have to convert this C program in assembly but the main registers are not enough,how can I add more variables in assembly? (without importing them from C) Or is there an easy way to reproduce this code in assembly?

The goal of the program is to compare the smallest string (S2) to the largest (S1) and save the position of the first character of the word in the array positions[] each time it is repeated in the string 1

so if

s1 = hello hello hellk s2 = he

the expected result is

positions [0] = 0
positions [1] = 6
positions [2] = 12
positionsLen = 3
int main()
{

    #define MAX_LEN 100

    //input
    char s1[] = "hello hello hellk"; //17 char
    unsigned int lenS1 = sizeof(s1) - 1;
    char s2[] = "he"; //2 char
    unsigned int lenS2 = sizeof(s2) - 1;
    //output
    unsigned int positions[MAX_LEN];
    unsigned int positionsLen;

    ////-------------------------------------------------------

        int i, j, found;
        int stringLen, searchLen;

        stringLen = lungS1; // length of string
        searchLen = lungS2; // length of word to be searched

        positionsLen = 0; //positions[] index
        for (i = 0; i <= stringLen - searchLen; i++) //repeats the times the string s2 enters the string s1
        {
            //flag the word like found
            found = 1;
            for (j = 0; j < searchLen; j++) //scroll through the characters of the string 2
            {
                if (s1[i + j] != s2[j]) //I compare the two strings character by character (the number of times as the size of the string 2)
                //if the characters are different, the word is not found
                {
                    found = 0;
                    break;
                }
            }

            if (found == 1)
            //if the word was found from position i to position i + searchlen
            {
                positions[positionsLen] = i;
                positionsLen++;
            }
        }
return 0;

What would be a solution to replicate this assembly program? This is my try, but it gives overflow problems due to too small registers.

__asm
        {
            //dichiaro le variabili

            XOR AH, AH //i + j
            XOR AL, AL //s1
            XOR BH, BH //found 
            XOR BL, BL //scambio
            XOR ECX, ECX //i e j ma uso solo CX
            XOR DH, DH //volte
            XOR DL, DL //s2
            MOV DH, lungS1
            SUB DH, lungS2 //volte sarà la differenza tra le due stringhe e quindi le volte che il loop esterno si ripeterà
            
            MOV positionsLen, 0 //assegno la lunghezza del vettore



            MOV CX, 0 //imposto la i a 0
            ext_loop: nop //for con i
            MOV BH, 1 //FLAG TROVATO A 1
            MOV BL, CX //BL = CX (i)
            MOV CX, 0 //imposto la j a 0
            /////////////////////////////////////////////////////
            int_loop : //for con j
            //devo rendere AH == i+J
            //quindi
            MOV AH, BL //AH = i
            ADD AH, CX //AH = AH + CX(j)
            MOV AL, s1[AH]
            MOV DL, s2[CX]
            CMP AL, DL // CMP S1[i+j] == s2[j]
            je jump1//se sono uguali salta alla fine dell'if
            MOV BH, 0 //FLAG TROVATO A 0
            jmp int_loop_end //BREAK
            jump1 :
            INC CX //incremento j
            CMP CX, lungS2 //se j<lungS2 il ciclo si ripete
            jl int_loop
            /////////////////////////////////////////////////////
            int_loop_end :
            //tramite BL che non ho modificato nel ciclo interno
            //faccio tornare cx la variabile i.
            //(la j non mi servirà più fino al prossimo ciclo interno)
            MOV CX, BL
            MOV BL, 0
            //inizio l'if per verificare che sia stata trovata
            //la parola che inizia alla posizione i
            test BH, BH //se uguale a 0 salta
            jz jump2
            MOV positions[positionsLen], CX
            INC positionsLen
            jump2 :
            INC CX //INCREMENTO LA i
            CMP CX, DH //COMPARO LA i A volte
            jl ext_loop //SE MINORE CONTINUA
        }
Bodo
  • 9,287
  • 1
  • 13
  • 29
  • 6
    Pass it to your compiler and ask it to dump the assembly it generates. – Jesper Juhl May 18 '22 at 07:26
  • You can make space on the stack for additional variables. But please note that this might cause unexpected results with inline assembly. – fuz May 18 '22 at 09:25

1 Answers1

1

Writing assembly code by your own to replicate a C code is very difficult and time consuming process. But, you can easily do this using any compiler (gcc, clang or msvc), it will generate assembly code of your C/C++ code.

Let's suppose your C file is named main.c:

Use this command to generate an assembly code named main.s:

gcc main.c -S

And you can optimize the final assembly code using optimization flags:

gcc -O3 -s -Og -masm=intel -march=native main.c -S
Darth-CodeX
  • 2,166
  • 1
  • 6
  • 23
  • Or if you like Intel syntax `gcc -S -masm=intel -o main.asm main.c`. Don't forget to add the optimization level, e.g. `-O0` to `-O3` as that will radically change the assembly that is produced. – David C. Rankin May 18 '22 at 08:18
  • Glad to. Good luck with your coding. – David C. Rankin May 18 '22 at 09:52
  • See also [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116) re: doing this on https://godbolt.org/ to get actual MSVC output. Note that `-Og` probably overrides `-O3`, so you get minimal optimization instead of full. `-m32 -O3 -fno-tree-vectorize` might be a good choice, if you don't want the compiler to go all out and use 16-byte XMM vector registers. The question needs 32-bit asm if it's going to put the code inside an MSVC inline asm block. – Peter Cordes May 18 '22 at 16:26