Reputation: 1
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
}
Upvotes: 0
Views: 76
Reputation: 2447
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
Upvotes: 1