|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
[Assembly x86] Perchè non posso "pushare" solo 8bit nello stack?
Ciao ragazzi,
mi trovavo nella situazione di dover "pushare" dei caratteri singoli nello stack di un programmino del cavolo che avevo fatto per imparare un po' l'assembly , quando mi sono accorto che , nonostante i caratteri siano 8bit di dimensione , venivano pushati 32bit di dati nello stack , così ho tentato di fargli pushare solo 8bit così : push byte 50 <codice ASCII per il mio carattere> (ASSEMBLATO CON NASM) ma non funziona , continua a pushare 32bit di roba, in sintassi AT&T sarebbe: pushb $50 ma se lo provo ad assemblare con GAS mi da un errore , ma è possibile pushare solo 32bit o no? Possibile che se devo passare delle Stringhe come parametri ad una funzione mi devo perdere 24bit per ogni carattere? La mia idea era quella dopo di usare una funzione per printare a schermo i caratteri che avevo pushato nello stack , così : Codice:
Supponendo: push byte 50 push byte 51 call print print: push ebp <Calling Function del C> mov ebp,esp <''> mov ebx, epb <Sposto epb in ebx> add ebx, 8 <Sommo 8 a ebx> mov edx, 2 <Uso la SYS CALL 4 di Linux , "EDX" numero di caratteri mov ecx, ebx (Lunghezza del buffer in byte), "ECX" indirizzo dell' inizio del mov ebx, 1 buffer, "EBX" File Descriptor , "EAX" Codice di della SYSCALL mov eax, 4 (4) > int 0x80 <Kernel Linux> 32 dovrebbe essere l'output , ma purtroppo dato che appunto la lunghezza del buffer è di 8byte anzichè 2byte come invece gli ho impostato nel registro EDX lui mi visualizza solo il "3" , se imposto ovviamente EDX a 8byte visualizzo i 2 caratteri , ma nello stack perdo 6byte di "0" ![]() ![]() Un altra cosa che volevo chiedere è questa : Per poter dare l'indirizzo del primo carattere ASCII ho dovuto usare questo inghippo : mov ebx, epb <Sposto epb in ebx> add ebx, 8 <Sommo 8 a ebx> Cioè quello di memorizzare EBP dentro EBX , e poi aggiungere 8 a EBX per ottenere in questo l'indirizzo di memoria del primo carattere , che poi passerò tramite REGISTER Addressing a ECX durante la Chiamata di sistema , ma mi chiedevo se non ci fosse un modo per integrare questo passaggio in un unica istruzione , del tipo : mov ecx, ebp + 8 ![]() Questa roba ovviamente non funziona (sennò non ve l'avrei chiesto ![]() Grazie delle risposte Ciao ![]() PS= Adesso che ci penso per la seconda invece che passare per EBX sarei potuto andare direttamente in ECX , ma comunque la domanda rimane , ossia se esite un modo per eseguire il Register Addressing in questo modo passando il valore modificato "on the fly" all' interno dell' unica istruzione (non so se mi sono spiegato)
__________________
GPU Compiler Engineer |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Aug 2001
Città: Milano
Messaggi: 402
|
Non ho ben capito se è una semplice prova o se vuoi fare un semplice passaggio di una stringa da una parte all'altra
![]() Se è valida la seconda alternativa allora devi passargli l'offset della stringa e non un carattere alla volta. Cmq l'istruzione Push ti permette di agire solo su valori a 16 o 32 bits, mentre x questo caso Codice:
mov ebx, ebp <Sposto epb in ebx> add ebx, 8 <Sommo 8 a ebx> Codice:
lea ebx, [ebp + 8] <Sposto epb in ebx e sommo 8>
__________________
Phenom 2 555 X2@X4@3,6Ghz 1.33v Asus M4A785TD-V EVO 4GB Team Group Elite 1333Mhz AC Freezer Xtreme Corsair 450VX Samsung SyncMaster T220 Hd Seagate 500x2(Raid 0) Barton 2500+@3200+ vcore 1.550 (liquid cooled@+9° T.A.) Asus A7N8X-E Dlx 1Gb Ram Dual DDR Hd Maxtor SATA 160x2(Raid 0) GeXCube 9600XT Eizo 19P Le belle cose hanno un inizio e una fine...tutto il resto è la normalità |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Ok mmx , tramite LEA mi hai fatto risolvere il primo problema
![]() Per il secondo non ho capito bene cosa intendi per "passare l'offset della stringa" (cosa intendi? e a cosa dovrei passarlo ? ) Ora, cercherò di spiegare meglio le mie intenzioni Quello che voglio io è dare come parametro alla funzione "print" del pezzo di programma precedente una stringa , caricandola carattere per carattere tramite "PUSH" , per poi farla visualizzare alla funzione tramite quella SYSCALL "4" che c'è nel programma . Ora, la domanda è , dato che non posso PUSHARE caratteri facendogli occupare solo 8 bit per volta, come faccio a caricare una stringa come parametro a una funzione ? L'unica alternativa è mettere una stringa nella [SECTION .data] del programma? Grazie CIao
__________________
GPU Compiler Engineer |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
La passi per indirizzo...
Supponi che il primo elemento della stringa sia memorizzato all'indirizzo contenuto in esi e che sia lunga 20 caratteri (ps non conosco la sintassi di NASM)... push dword esi push dword 20 call print print: push ebp <Calling Function del C> mov ebp,esp <''> add ebp, 8 mov edx, [ebp - 4] <Uso la SYS CALL 4 di Linux , "EDX" numero di caratteri mov ecx, [ebp - 8] (Lunghezza del buffer in byte), "ECX" indirizzo dell' inizio del mov ebx, 1 buffer, "EBX" File Descriptor , "EAX" Codice di della SYSCALL mov eax, 4 (4) > int 0x80 <Kernel Linux> Ultima modifica di cionci : 21-05-2004 alle 10:32. |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Quote:
Fammi capire quello che hai fatto : In pratica tu hai memorizzato la stringa di caratteri in un altro punto nella memoria , e poi hai pushato l'indirizzo del primo carattere + lunghezza del carattere nello stack per poi andarli a ripescare con [ebp - 4] e [ebp - 8] , giusto? Grazie Ciao
__________________
GPU Compiler Engineer |
|
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
|
|
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Comunque ho sbgliato l'ordine:
push dword 20 push dword esi Oppure semplicemente inverti il -4 con il -8... |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Quote:
Ok, soltanto una cosa , non dovrebbe essere [ebp + 4] [ebp + 8] ? Lo stack cresce verso il basso , perciò tecnicamente i dati pushati stanno sopra all' attuale valore puntato da EBP , o sbaglio? Ciao
__________________
GPU Compiler Engineer |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Aug 2001
Città: Milano
Messaggi: 402
|
State facendo un pò do confusione
![]() Il codice corretto è questo Codice:
Push DWord Ptr ESI <offset> Push DWord Ptr 020 <lunghezza> Call Print Print: Push EBP Mov EBP, ESP Add EBP, 8 Mov EDX, [EBP] <lunghezza> Mov ECX, [EBP + 4] <offset> Spero di essere stato kiaro ![]()
__________________
Phenom 2 555 X2@X4@3,6Ghz 1.33v Asus M4A785TD-V EVO 4GB Team Group Elite 1333Mhz AC Freezer Xtreme Corsair 450VX Samsung SyncMaster T220 Hd Seagate 500x2(Raid 0) Barton 2500+@3200+ vcore 1.550 (liquid cooled@+9° T.A.) Asus A7N8X-E Dlx 1Gb Ram Dual DDR Hd Maxtor SATA 160x2(Raid 0) GeXCube 9600XT Eizo 19P Le belle cose hanno un inizio e una fine...tutto il resto è la normalità |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Sì...ho fatto un po' di casino...comunque l'idea era quella (è un po' che non metto amno a queste cose)...
|
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Ok, grazie ragazzi , ora mi sfugge solo un concetto del (anzi 2 ) del programma di mmx[ngg] .
Mov EDX, [EBP] <lunghezza> Perchè? [EBP] non dovrebbe puntare al vecchio valore di EBP che è stato inserito nello Stack con "Push EBP" all' inizio della funzione? Un altra cosa : Push DWord cosa fa precisamente ? DWord si intende Double Word? Double Word sono 2 o 4 byte in un sistema a 32bit? Grazie della pazienza ![]()
__________________
GPU Compiler Engineer |
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Aug 2001
Città: Milano
Messaggi: 402
|
Dunque...partiamo con le cose facili
![]() Byte Ptr = 8 bits Word Ptr = 16 bits DWord Ptr = 32 bits QWord Ptr = 64 Bits Poi... Supponi ke ESP sia 20, quindi : Codice:
Push ESI ESP diventa 16 e punta al valore di ESI (se fai Mov ESI, [ESP] lo verifichi) Push 20 ESP = 12 e punta al volore 20 Call Print ESP = 8 e punta all EIP successivo (al max questo te lo spiego dopo) Print: Push EBP ESP = 4 e punta a EBP Mov EBP, ESP EBP = ESP cioè 4 Add EBP, 8 EBP = 12, quindi punta a 20 Tutte le istruzioni sono presenti in un offset (indirizzo) di memoria gestito in modo automatico dal registro IP (EIP a 32 bits)..quindi : Codice:
Push ESI offset 100h Push 20 offset 101h (ossia l'indirizzo iniziale + la lunghezza dell'istruzione precedente...appunto 1 bytes) Call Print offset 106h (push 20 è di 5 bytes) ora nello stack la cpu salva l'offset + la lunghezza dell'istruzione call e quindi 10Bh Xor EAX, EAX offset 10Bh Print: NOP Ret imposta EIP dallo stack quindi torna all'offset 10Bh
__________________
Phenom 2 555 X2@X4@3,6Ghz 1.33v Asus M4A785TD-V EVO 4GB Team Group Elite 1333Mhz AC Freezer Xtreme Corsair 450VX Samsung SyncMaster T220 Hd Seagate 500x2(Raid 0) Barton 2500+@3200+ vcore 1.550 (liquid cooled@+9° T.A.) Asus A7N8X-E Dlx 1Gb Ram Dual DDR Hd Maxtor SATA 160x2(Raid 0) GeXCube 9600XT Eizo 19P Le belle cose hanno un inizio e una fine...tutto il resto è la normalità |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Ok , Grazie
![]()
__________________
GPU Compiler Engineer |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:40.