Fatto strano

di il
2 risposte

Fatto strano

Salve a tutti
questo e il codice di prova di una routine che sto' scrivendo giusto per esercitarmi nel passaggio di parametri tra c++ e assembler.
// leftstringa.cpp : definisce il punto di ingresso dell'applicazione console.
//
#include "stdafx.h"
#include "iostream"
using std::cin;
using std::cout;
using std::endl;
                      
extern "C" int __stdcall pleftstringa(char *,char *,int);
int _tmain(int argc, _TCHAR* argv[])
    {
		char pippo[31],pluto[31];
		for (int indy=0;indy<31;indy++)
		   { pippo[indy] = ' '; pluto[indy] = ' '; }
		int ncar,err;ncar = 0; err = 0;
		cout << "inserisci una stringa : ";
		cin >> pippo;
		cout << "inserisci il numero dei caratteri da prendere : ";
		//cin.clear();
		cin >> ncar;
		if (ncar==0) { cout << "non hai specificato il numero dei caratteri da prendere "; return 0; }
		cout << "\n entriamo nella parte assembly \n";
		if (ncar > 31) { cout << "richiesta caratteri maggiore della lunghezza della stringa"; return 0; }
		err=pleftstringa(pippo,pluto,ncar);
		cout <<  "la stringa originale e' : " << pippo << "\n";
		cout <<  "la stringa prelevate e' : " << pluto << "\n";
	return 0;
    }
il problema che ho riscontrato ed è ,per me un fatto strano, mentre la cin iniziale viene sempre eseguita la seconda cin viene eseguita solo se io nella prima cin non immetto spazi.
esempio:
se io introduco nella prima cin introduco solo topolino la seconda cin viene eseguita
mentre se io nella prima cin introduco topolino e pippo la seconda cin non viene eseguita.
mi chiedevo come mai succede una cosa del genere e come potrei porci rimedio.
premetto che quando la seconda cin funziona il programma funziona correttamente quindi l'errore non stà nella routine assembler.
posto anche il sorgente assembler cosi chiunque sia interessato all'argomento del passaggio dei parametri può prendere spunto.
.486 ; serve per selezionare il set di istruzioni da utilizzare 
     .model flat,stdcall ; modello di memoria e tipo di chiamata per il passaggio dei parametri
      option casemap :none ; non ricordo a cosa serva ma serve!
     .code ; inizio del segmento del codice
	  pleftstringa PROC Arg1:DWORD,Arg2:DWORD,Arg3:DWORD
; pleftstringa è il nome della funzione che è stata definita in c++ qui viene definita come procedura come da assembler richiesto
; arg1:dword  sarebbe il primo parametro della funzione
; arg2:dword  sarebbe il secondo parametro della funzione
; arg3: dword sarebbe il terzo parametro della funzione
; la clausola dword va utilizzata se i parametri sono di tipo int,unsign,char o puntatori.
;se si vogliono usare dei double, long int o dei float il tipo da utilizzare è "qword"
            	mov ecx,Arg3 ; carico il terzo parametro 
         ; vi ricordo che i parametri nello stack vengono messi all'inverso rispetto 
         ;a come vengono  dichiarati nella funzione c++ 
        ;esempio funzx(int a,int b,int c)
        ;nello stack avremo int c,int b,int a 
                mov edi,Arg2 ; carico parametro 2
                mov esi,Arg1 ; carico parametro 1
                xor eax,eax ; azzero il codice di ritorno della funzione
		rep movsb ; eseguo l'operazione di copia dei byte che mi interessano
		mov dword ptr [edi],0 ; metto un null terminatore nella stringa che ho copiato prima
                ret ; ritorno al programma che ha chiamato la routine
      pleftstringa endp ; dico al programma che il codice della funzione e finito
                  end ; indico che il programma e finito
;avvertimenti
1) non definite mai la funzione con lo stesso nome del programma c++ vi darà errore e andrete al manicomio per capire come correggere l'errore.
2) quando definite una funzione in assembler sappiate che direttamente può restituire solo int e char tramite il registro eax se vote fargli restituire un double,float o long int prevedete un parametro all'interno della funzione. 
"extern "C" int __stdcall pleftstringa(char *,char *,int)" 

2 Risposte

  • Re: Fatto strano

    Il cin si ferma se trova uno spazio. se vuoi leggere topolino e pluto in una stringa unica devi usare getline.
  • Re: Fatto strano

    smalldragon ha scritto:


    2) quando definite una funzione in assembler sappiate che direttamente può restituire solo int e char tramite il registro eax se vote fargli restituire un double,float o long int prevedete un parametro all'interno della funzione.
    Non è proprio così ... se devi restituire un double, anche se non usi eax, puoi usare una istruzione

    fld qword ptr [var1]

    caricando in ST0 nel coprocessore matematico il valore da restituire.
    Il chiamante eseguirà una

    fstp qword ptr [var2]

    per ottenere il valore double risultato della chiamata.

    Per il "long int" forse intendevi il "long long int". In questo caso, molti compilatori ammettono la restituzione del valore in DX:AX
Devi accedere o registrarti per scrivere nel forum
2 risposte