// Main

// Prologo

0x5555523d <+0>: push rbp
0x5555523e <+1>: mov rbp,rsp
0x55555241 <+4>: sub rsp,0x30 // crea spazio nello stack per le variabili locali
0x55555245 <+8>: mov DWORD PTR [rbp-0x24],edi
0x55555248 <+11>: mov QWORD PTR [rbp-0x30],rsi

// malloc per la stringa

0x5555524c <+15>: mov edi,0xf
0x55555251 <+20>: call0x555555555070 <malloc@plt>
0x55555256 <+25>: mov QWORD PTR [rbp-0x8],rax // potrebbe essere quello che ritorna il malloc, un indirizzo, che poi viene assegnato strres

// printf

0x5555525a <+29>: lea rdi,[rip+0xda7] // stringa da passare alla printf
0x55555261 <+36>: mov eax,0x0
0x55555266 <+41>: call0x555555555050 <printf@plt>

// fgets

0x5555526b <+46>: mov rdx,QWORD PTR [rip+0x2dee] // indirizzo stdin <stdin@@GLIBC_2.2.5>
0x55555272 <+53>: lea rax,[rbp-0x17] // variabile str
0x55555276 <+57>: mov esi,0xf // parametro 15
0x5555527b <+62>: mov rdi,rax
0x5555527e <+65>: call0x555555555060 <fgets@plt> // fscanf

// printf

0x55555283 <+70>: lea rdi,[rip+0xd96] # 0x555555556020
0x5555528a <+77>: mov eax,0x0
0x5555528f <+82>: call0x555555555050 <printf@plt>

// scanf

0x55555294 <+87>: lea rax,[rbp-0x18] // variabile ch
0x55555298 <+91>: mov rsi,rax
0x5555529b <+94>: lea rdi,[rip+0xda5] //format string
0x555552a2 <+101>: mov eax,0x0
0x555552a7 <+106>: call0x555555555080 <__isoc99_scanf@plt>

// call removechar

0x555552ac <+111>: movzx eax,BYTE PTR [rbp-0x18] // da 8 bit a 32 bit inserendo 0
0x555552b0 <+115>: movsx edx,al // da 8 bit a 32 bit estendendo il segno
0x555552b3 <+118>: lea rax,[rbp-0x17] // variabile str
0x555552b7 <+122>: mov esi,edx
0x555552b9 <+124>: mov rdi,rax
0x555552bc <+127>: call0x555555555185 <removechar> // chiamata alla funzione removechar

// printf

0x555552c1 <+132>: mov QWORD PTR [rbp-0x8],rax //c'è il valore di ritorno delle funzione?
0x555552c5 <+136>: mov rax,QWORD PTR [rbp-0x8] // perchè rimetterlo in rax?
0x555552c9 <+140>: mov rsi,rax // strres
0x555552cc <+143>: lea rdi,[rip+0xd77] // format string # 0x55555555604a
0x555552d3 <+150>: mov eax,0x0
0x555552d8 <+155>: call0x555555555050 <printf@plt>

// ret

0x555552dd <+160>: mov eax,0x0
0x555552e2 <+165>: leave
0x555552e3 <+166>: ret

// removechar

// Dump of assembler code for function removechar:

// prologo

0x55555185 <+0>: push rbp
0x55555186 <+1>: mov rbp,rsp
0x55555189 <+4>: sub rsp,0x30
0x5555518d <+8>: mov QWORD PTR [rbp-0x28],rdi // rbp-0x28 indirizzo di str


0x55555191 <+12>: mov eax,esi
0x55555193 <+14>: mov BYTE PTR [rbp-0x2c],al // rbp-0x2c c'è il carattere
0x55555196 <+17>: mov DWORD PTR [rbp-0x8],0x0

// strlen

0x5555519d <+24>: mov rax,QWORD PTR [rbp-0x28] // rbp-0x28, str
0x555551a1 <+28>: mov rdi,rax
0x555551a4 <+31>: call0x555555555040 <strlen@plt>
0x555551a9 <+36>: mov DWORD PTR [rbp-0xc],eax // rbp-0xc, n

// malloc

0x555551ac <+39>: mov edi,0xf
0x555551b1 <+44>: call0x555555555070 <malloc@plt>
0x555551b6 <+49>: mov QWORD PTR [rbp-0x18],rax // rbp-0x18, strres


0x555551ba <+53>: mov DWORD PTR [rbp-0x4],0x0 // j=0
0x555551c1 <+60>: jmp 0x555555555213 <removechar+142> // salta a j<n


0x555551c3 <+62>: mov eax,DWORD PTR [rbp-0x4] // valore di i
0x555551c6 <+65>: movsxd rdx,eax // estende da 32 a 64 bit con il segno
0x555551c9 <+68>: mov rax,QWORD PTR [rbp-0x28] // indirizzo di str
0x555551cd <+72>: add rax,rdx // a cui aggiungiamo i, visto che si tratta di char
0x555551d0 <+75>: movzx eax,BYTE PTR [rax] // mette in eax il carattere iesimo
0x555551d3 <+78>: cmp BYTE PTR [rbp-0x2c],al // e lo compara a il ch passato alla funzione
0x555551d6 <+81>: je 0x55555555520f <removechar+138>

// il blocco seguente mette in OR la prima condzione negata con la seconda :
// if (str[i]!=ch && str[i]!='\0') { -> if (str[i]==ch || str[i]=='\0') {
// leggi di De Morgan , una AND di due espressioni negate diventa una OR di due espressioni non negate

0x555551d8 <+83>: mov eax,DWORD PTR [rbp-0x4]
0x555551db <+86>: movsxd rdx,eax
0x555551de <+89>: mov rax,QWORD PTR [rbp-0x28]
0x555551e2 <+93>: add rax,rdx // str + i
0x555551e5 <+96>: movzx eax,BYTE PTR [rax] // contenuto di str[i]
0x555551e8 <+99>: test al,al // confronto con il byte null
0x555551ea <+101>: je 0x55555555520f <removechar+138> // salta all'incremento di i

// blocco di costruzione della nuova stringa senza il carattere da rimuovere, copiando i caratteri dalla
// vecchia stringa

0x555551ec <+103>: mov eax,DWORD PTR [rbp-0x4] // i
0x555551ef <+106>: movsxd rdx,eax // esteso a 64 bit con segno
0x555551f2 <+109>: mov rax,QWORD PTR [rbp-0x28] // str
0x555551f6 <+113>: add rax,rdx // str + i
0x555551f9 <+116>: mov edx,DWORD PTR [rbp-0x8] // j
0x555551fc <+119>: movsxd rcx,edx // esteso a 64 bit con segno in rcx
0x555551ff <+122>: mov rdx,QWORD PTR [rbp-0x18] // strres
0x55555203 <+126>: add rdx,rcx // strres + j
0x55555206 <+129>: movzx eax,BYTE PTR [rax] // valore di str[i]
0x55555209 <+132>: mov BYTE PTR [rdx],al // in strres + j ci metto il carattere str[i]
0x5555520b <+134>: add DWORD PTR [rbp-0x8],0x1 // incremento j

// incremento di i e confronto con n

0x5555520f <+138>: add DWORD PTR [rbp-0x4],0x1 // incrementa i
0x55555213 <+142>: mov eax,DWORD PTR [rbp-0x4] // i
0x55555216 <+145>: cmp eax,DWORD PTR [rbp-0xc] // i<n
0x55555219 <+148>: jl 0x5555555551c3 <removechar+62> // se è minore torno indietro

// blocco che setta l'ultimo carattere della strres a \0

0x5555521b <+150>: mov eax,DWORD PTR [rbp-0x8]
0x5555521e <+153>: movsxd rdx,eax
0x55555221 <+156>: mov rax,QWORD PTR [rbp-0x18]
0x55555225 <+160>: add rax,rdx
0x55555228 <+163>: mov BYTE PTR [rax],0x0

// printf della strres

0x5555522b <+166>: mov rax,QWORD PTR [rbp-0x18]
0x5555522f <+170>: mov rdi,rax
0x55555232 <+173>: call0x555555555030 <puts@plt>

// ret

0x55555237 <+178>: mov rax,QWORD PTR [rbp-0x18] // in reax ci metto l'indirizzo della stringa risultato

0x5555523b <+182>: leave
0x5555523c <+183>: ret

// C Code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* removechar(char* str, char ch)
{

char* strres;
int n,i,j;
j=0;

n=strlen(str);

strres=malloc(15*sizeof(char));

for (i=0; i<n; i++) {
if (str[i]!=ch && str[i]!='\0') {
strres[j]=str[i];
j++;
}

}
strres[j]='\0';
printf("%s\n",strres);
return strres;


}


int main(int argc, char** argv) {

char str[15];
char* strres;
strres=malloc(15*sizeof(char));

printf("Inserisci la stringa : ");
fgets(str, 15, stdin);
char ch;

printf("Inserisci il carattere da rimuovere : ");
scanf("%c",&ch);

strres=removechar(str,ch);
printf("la stringa finale è %s",strres);


return 0;

}

// primi 4 byte indirizzo 0x00005555;

// prologo :

55555145 <+0>: push rbp
55555146 <+1>: mov rbp,rsp
55555149 <+4>: sub rsp,0x50 // qui crea lo spazio anche per l'array di interi

// non ho ben copreso ma potrebbe essere che mette in queste due locazioni, argc e *argv[], in effetti l'int è un DWORD, mentre l'indirizzo è un QWORD;

5555514d <+8>: mov DWORD PTR [rbp-0x44],edi
55555150 <+11>: mov QWORD PTR [rbp-0x50],rsi

// variabili intere;

55555154 <+15>: mov DWORD PTR [rbp-0xc],0xa
5555515b <+22>: mov DWORD PTR [rbp-0x8],0x0
55555162 <+29>: mov DWORD PTR [rbp-0x4],0x0
55555169 <+36>: jmp 0x5555555551ae <main+105> // qui salta al for;

// dovrebbe essere il blocco per puntare a arr[i] per poi passarlo alla scanf;

5555516b <+38>: lea rax,[rbp-0x40]
5555516f <+42>: mov edx,DWORD PTR [rbp-0x4] // mette in edx l'indice i;
55555172 <+45>: movsxd rdx,edx // da DWORD a QWORD;
55555175 <+48>: shl rdx,0x2 // questo doppio shift a sinistra trova il numero da;
55555179 <+52>: add rax,rdx // aggiungere a rax (che punta all'inizio dell'array) per puntare all'iesimo elemento di arr in memoria visto che ogni int sono 4 byte;

// la scanf che i due parametri, nell'rsi l'indirizzo di arr[i] e nel rdi il format string;

5555517c <+55>: mov rsi,rax
5555517f <+58>: lea rdi,[rip+0xe7e] # 0x555555556004
55555186 <+65>: mov eax,0x0
5555518b <+70>: call 0x555555555040 <__isoc99_scanf@plt>

// l'if per vedere se è il nuovo max e aggiornare la variabile max;

55555190 <+75>: mov eax,DWORD PTR [rbp-0x4] // questo è il valore di i;
55555193 <+78>: cdqe // qui viene convertito da eax a rax;
55555195 <+80>: mov eax,DWORD PTR [rbp+rax*4-0x40] // qui viene ricavato il valore di arr[i];
55555199 <+84>: cmp DWORD PTR [rbp-0x8],eax // se max è piu grande salta a 101 e incrementa i;
5555519c <+87>: jg 0x5555555551aa <main+101>

// se abbiamo il nuovo max;

5555519e <+89>: mov eax,DWORD PTR [rbp-0x4]
555551a1 <+92>: cdqe
555551a3 <+94>: mov eax,DWORD PTR [rbp+rax*4-0x40]
555551a7 <+98>: mov DWORD PTR [rbp-0x8],eax // viene assegnato a max il valore di arr[i]

// incremento della variabile i;

555551aa <+101>: add DWORD PTR [rbp-0x4],0x1

// for (i=0; i<n; i++), la pare della comparazione, tra rbp-0x04 che è la i, e rbp-0xc che è a quindi 10;

555551ae <+105>: mov eax,DWORD PTR [rbp-0x4]
555551b1 <+108>: cmp eax,DWORD PTR [rbp-0xc]
555551b4 <+111>: jl 0x55555555516b <main+38>

// la funzione printf che stampa il max valore dell'array;

555551b6 <+113>: mov eax,DWORD PTR [rbp-0x8]
555551b9 <+116>: mov esi,eax
555551bb <+118>: lea rdi,[rip+0xe45] // stringa printf # 0x555555556007
555551c2 <+125>: mov eax,0x0
555551c7 <+130>: call 0x555555555030 <printf@plt>

// ret;

555551cc <+135>: mov eax,0x0
555551d1 <+140>: leave
555551d2 <+141>: ret


#include <stdio.h>

int main(int argc, char** argv)
{

int arr[10];int n=10;
int i;
int max=0;

for (i=0; i<n; i++) {
scanf("%d",&arr[i]);
if (arr[i]>=max) max=arr[i];
}

printf("il massimo è %d\n:", max);
return 0;

 }