Newsgroup: it.comp.lang.c
Titolo: dall'assembler al C

Ho una routine realizzata in assembler ed un programmino in C che
vorrebbe sfruttarla?
Ma non riesco a "mettere insieme" le due cose...
Qualche anima buona puo' spiegarmi quale e' la procedura per
richiamare dal C una funziona programmata in assembler?
sentitamente grazie
orlando

...

Qual'e' il problema? Hai gia' fatto le cose "elementari", tipo vedere come
il compilatore C passa i parametri; stai usando lo stesso modello di memoria
(se il tutto e' a 16 bit)? Quale compilatore C usi? Riesci a produrre un
.obj corretto per la tua routine assembler?
Tanto per darti un esempio di passaggio di parametri:
.MODEL LARGE
        PAGE    60,132
        TITLE   Cancella file
;***************************************************************************
****
; UTKILL - Cancella file richiesto       Rel 1.0 giu 90
;***************************************************************************
****
;
;       uso:    utkill  (filename, esito)
;
;               filename - char 72         -  file name da cancellare
;
;               esito    - short  -  (0)  kill ok
;
;***************************************************************************
****
;---------------------------------------------------------------------------
---;
;   Routine parameters
;
;---------------------------------------------------------------------------
---;
PARBLK      STRUC
            DW      ?                   ; old bp
            DD      ?                   ; return address
            PATH        DD      ?                   ; address "     "
            RETCODE     DD      ?                   ; address "     "
            PATH_LEN    DW      ?                   ; length 1st parameter
(filename)
            L_RETC      DW      ?                   ; length 2nd parameter
(esito)
            PARBLK      ENDS
            PUBLIC  UTKILL              ; external name
.CODE
            SUBTTL  Equates and work area
            PAGE
;---------------------------------------------------------------------------
---;
;   Equates and internal work area
;
;---------------------------------------------------------------------------
---;
WK_PATH_LEN EQU     72                  ; max length for path name
WK_PATH     DB      73  DUP(?)
            SUBTTL  Main program
            PAGE
UTKILL      PROC    FAR
            PUSH    BP
            MOV     BP,SP               ; point to parblk on stack
            PUSH    DS                  ; save segment register
            PUSH    ES
            CLD                         ; clear direction flag
            LDS     SI,[BP].PATH        ; [DS:SI] --> Path name
            PUSH    CS
            POP     ES
            LEA     DI, CS:WK_PATH      ; [ES:DI] --> wk_path
            MOV     CX, [BP].PATH_LEN
.........
UTKILL      ENDP
            END


Dipende dall'ambiente.
In generale, i compilatori C aggiungono un underscore '_' a tutti i nomi
esterni, passano i parametri sullo stack in ordine inverso, il chiamante si
occupa di rimuoverli e si aspetta eventuali ritorni in registri specifici.
Per scoprire esattamento cosa combina il tuo compilatore dovresti provare a
guardare l'assemblrer prodotto da un piccolo programma di prova con una
chiamata a funzione simile a quella che ti serve.
Di solito la chiamata:
	extern int Routine(int arg1, int arg2);
	int x=Routine(int arg1, int arg2);
viene tradotta in:
	push arg2
	push arg1
	call _Routine
	mov x, ax					; per CPU Intel x86 - risultato nel registro AX
	add sp, sizeof(arg1)+sizeof(arg2)	; rimuove arg2 e arg1 dallo stack
Nei compilatori per x86 e' sempre possibile specificare la modalita' di
rimozione degli argomenti:
	_cdecl Routine(...)	// C standard: il chiamante rimuove gli argomenti
	_fastcall Routine(...)	// il chiamato rimuove gli argomenti
Qundi devi verificare cosa si aspetta la tua routine assembler, se rimuove
da sola gli argomenti e se  il nome e' conforme allo standard del tuo
compilatore (con o senza '_' iniziale) in modo da chiamarla in modo
corretto (invertire l'ordine degli argomenti ecc.)
Eventualmente potresti scrivere una routine assembler di interfaccia che
converta una chiamata standard nella chiamata alla tua routine.