PDA

View Full Version : [c++]risultato compilazione


nuovoUtente86
02-04-2008, 19:13
Il risultato dell compilazione di un file cpp o piu in generale di un linguaggio compilato genera linguaggio macchina oppure istruzioni assembly che verrano poi interpretate dal livello virtuale 2?

cdimauro
02-04-2008, 20:24
Dipende esclusivamente dal compilatore e della piattaforma di riferimento.

Ad esempio è possibilissimo compilare un sorgente C++ in bytecode (o negli assembly di .NET) e NON in formato oggetto/eseguibile/binario.

cionci
03-04-2008, 09:20
Il risultato dell compilazione di un file cpp o piu in generale di un linguaggio compilato genera linguaggio macchina oppure istruzioni assembly che verrano poi interpretate dal livello virtuale 2?
Solitamente il risultato principale è linguaggio oggetto, che è un linguaggio macchina con riferimenti "aperti" per alcune funzioni/metodi che devono essere forniti da moduli esterni. Il linker penserà a sostituire questi riferimenti aperti con i riferimenti corretti al momento in cui assemblerà i file oggetto che compongono l'eseguibile.

E' comunque possibile che in un passaggio intermedio della compilazione il compilatore generi codice assembly per poi poter applicare delle ottimizzazioni.
Tra l'altro in molti compilatori è possibile ottenere il codice assembly equivalente del file oggetto passando un parametro durante la compilazione.

nuovoUtente86
04-04-2008, 00:44
Solitamente il risultato principale è linguaggio oggetto, che è un linguaggio macchina con riferimenti "aperti" per alcune funzioni/metodi che devono essere forniti da moduli esterni. Il linker penserà a sostituire questi riferimenti aperti con i riferimenti corretti al momento in cui assemblerà i file oggetto che compongono l'eseguibile.

E' comunque possibile che in un passaggio intermedio della compilazione il compilatore generi codice assembly per poi poter applicare delle ottimizzazioni.
Tra l'altro in molti compilatori è possibile ottenere il codice assembly equivalente del file oggetto passando un parametro durante la compilazione.
In sostanza la compilazione è uguale a quella del C,cioè il compilatore crea dal sorgente l' assembly e poi l' assemblatore crea il codice macchina che poi il linker "renderà" eseguibile! Sotto windows con quale compilatore posso ottenere appunto l' assembly intermedio?

nuovoUtente86
04-04-2008, 00:47
Dipende esclusivamente dal compilatore e della piattaforma di riferimento.

Ad esempio è possibilissimo compilare un sorgente C++ in bytecode (o negli assembly di .NET) e NON in formato oggetto/eseguibile/binario.

Si sapevo che era possibile compilare C++ per il runtime di .Net ma in byteCode da quale macchina virtuale lo si fa poi interpretare?

gugoXX
04-04-2008, 02:06
Si sapevo che era possibile compilare C++ per il runtime di .Net ma in byteCode da quale macchina virtuale lo si fa poi interpretare?

Dalla CLR integrata del NET, che mediante il JIT interpreta il CIL... :fagiano:

Beh, in altre parole quando compili per .NET viene creato un bytecode in CIL, ovvero common integrate language.
Quanto questo CIL viene eseguito, viene compilato al volo dalla CLR (Common Language Runtime), da parte del JIT Compiler, ovvero il Just-In-Time compiler.
Questo compilatore compila e "impara", nel senso che puo' cambiare al volo il codice compilato, a seconda del flusso di esecuzione.
Tipico esempio e' quello della impossibilita' di mettere funzioni __inline in C++.NET
Ma perche' non serve. E' il JIT che al volo cerca di capire se una funzione deve (o deve diventare da un certo punto in poi) una funzione inline, e se del caso la rende tale.
Occhio che il C++.NET e' un linguaggio diverso dal VC++, e richiedono compilatori diversi (Il primo produce il JIT, il secondo dopo il LINK produce un eseguibile classico)

Il CIL e' un codice assembly, un assembly "inventato" da Microsoft, ma plausibile per un processore, tanto che ci sono progetti di hardware che potrebbero usarlo direttamente (.net Hardware)

^TiGeRShArK^
04-04-2008, 09:19
Beh, in altre parole quando compili per .NET viene creato un bytecode in CIL, ovvero common integrate language.

Common Intermediate Language :fiufiu:
:p

gugoXX
04-04-2008, 09:21
Common Intermediate Language :fiufiu:
:p


E gia' :p

cionci
04-04-2008, 09:35
In sostanza la compilazione è uguale a quella del C,cioè il compilatore crea dal sorgente l' assembly e poi l' assemblatore crea il codice macchina che poi il linker "renderà" eseguibile!
Perché avrebbe dovuto essere diverso ?
Comunque sotto Windows per i compilatore Gcc-style c'è sempre l'opzione -S.

nuovoUtente86
04-04-2008, 11:54
Dalla CLR integrata del NET, che mediante il JIT interpreta il CIL... :fagiano:

Beh, in altre parole quando compili per .NET viene creato un bytecode in CIL, ovvero common integrate language.
Quanto questo CIL viene eseguito, viene compilato al volo dalla CLR (Common Language Runtime), da parte del JIT Compiler, ovvero il Just-In-Time compiler.
Questo compilatore compila e "impara", nel senso che puo' cambiare al volo il codice compilato, a seconda del flusso di esecuzione.
Tipico esempio e' quello della impossibilita' di mettere funzioni __inline in C++.NET
Ma perche' non serve. E' il JIT che al volo cerca di capire se una funzione deve (o deve diventare da un certo punto in poi) una funzione inline, e se del caso la rende tale.
Occhio che il C++.NET e' un linguaggio diverso dal VC++, e richiedono compilatori diversi (Il primo produce il JIT, il secondo dopo il LINK produce un eseguibile classico)

Il CIL e' un codice assembly, un assembly "inventato" da Microsoft, ma plausibile per un processore, tanto che ci sono progetti di hardware che potrebbero usarlo direttamente (.net Hardware)Perfetto, questo è quello che fa il .NEt
ma questo intervento
Dipende esclusivamente dal compilatore e della piattaforma di riferimento.

Ad esempio è possibilissimo compilare un sorgente C++ in bytecode (o negli assembly di .NET) e NON in formato oggetto/eseguibile/binario.
sembrava riferirsi all' assembly per .Net e al bytecode come cose diverse.Forse ho inteso male io.

Per quanto riguarda il Vc++ mi sembra sia anche possibile generare codice intermedio invece che binario ?

variabilepippo
04-04-2008, 12:39
Sotto windows con quale compilatore posso ottenere appunto l' assembly intermedio?

Quasi tutti supportano degli switch da command-line per generare i file .asm dal codice sorgente.

Per esempio con Visual C++ puoi ottenere


; Listing generated by Microsoft (R) Optimizing Compiler Version 14.00.50727.762

TITLE test.c
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC ??_C@_0M@DIMJODLI@CIAO?5MONDO?$CB?$AA@ ; `string'
PUBLIC _main
EXTRN _puts:PROC
; COMDAT ??_C@_0M@DIMJODLI@CIAO?5MONDO?$CB?$AA@
; File test.c
CONST SEGMENT
??_C@_0M@DIMJODLI@CIAO?5MONDO?$CB?$AA@ DB 'CIAO MONDO!', 00H ; `string'
; Function compile flags: /Ogtpy
CONST ENDS
; COMDAT _main
_TEXT SEGMENT
_main PROC ; COMDAT
; Line 4
push OFFSET ??_C@_0M@DIMJODLI@CIAO?5MONDO?$CB?$AA@
call _puts
add esp, 4
; Line 5
xor eax, eax
; Line 6
ret 0
_main ENDP
_TEXT ENDS
END


partendo da


/* prova.c */
#include <stdio.h>

int main(void){
puts("CIAO MONDO!");
return 0;
}


con il comando cl /Faprova.asm prova.c.

variabilepippo
04-04-2008, 12:41
I file con estensione .cpp possono essere compilati anche con l'opzione /clr, in tal caso si ottiene:


file "prova.cpp"
.rdata

$SG6926:
.ascii "CIAO MONDO!\000"
.bss
.local $T6944,0
; Function compile flags: /Odtp
.text
.global ?main@@$$HYAHXZ ; main
?main@@$$HYAHXZ: ; main
; .proc.def D:I()

; Function Header:
; max stack depth = 1
; function size = 17 bytes
; local varsig tk = 0x11000001
; Exception Information:
; 0 handlers, each consisting of filtered handlers

; .local.i4 0,"$T6943" SIG: i4

; .proc.beg
; File prova.cpp
; Line 5
ldc.i.0 0 ; i32 0x0
stloc.0 ; $T6943
ldsflda $SG6926
call ?puts@@$$J0YAHPBD@Z
pop
; Line 6
ldc.i.0 0 ; i32 0x0
stloc.0 ; $T6943
; Line 7
ldloc.0 ; $T6943
ret
.end ?main@@$$HYAHXZ ; main
; .proc.end.i4
_TEXT ENDS
PUBLIC __mep@?main@@$$HYAHXZ
PUBLIC _main
; COMDAT __mep@?main@@$$HYAHXZ
data SEGMENT
__mep@?main@@$$HYAHXZ TOKEN 0A000009
; Function compile flags: /Odtp
data ENDS
; COMDAT _main
_TEXT SEGMENT
_main PROC ; COMDAT
jmp DWORD PTR __mep@?main@@$$HYAHXZ
_main ENDP
_TEXT ENDS
END

nuovoUtente86
04-04-2008, 12:48
Grazie!Il file. asm è uguale al .s?

variabilepippo
04-04-2008, 12:53
Il file. asm è uguale al .s?


Cosa intendi per "uguale"?

Ogni compilatore genera un codice binario diverso, quindi i file .asm/.s in generale non sono uguali se creati da compilatori differenti.

Per esempio GNU GCC tira fuori (partendo dall'Hello World) il seguente file prova.s:


.file "test.c"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "CIAO MONDO!\0"
.text
.p2align 4,,15
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $4, %esp
call ___main
movl $LC0, (%esp)
call _puts
addl $4, %esp
xorl %eax, %eax
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.def _puts; .scl 2; .type 32; .endef


Se preferisci la sintassi Intel:


.file "test.c"
.intel_syntax
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "CIAO MONDO!\0"
.text
.p2align 4,,15
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
lea ecx, [esp+4]
and esp, -16
push DWORD PTR [ecx-4]
push ebp
mov ebp, esp
push ecx
sub esp, 4
call ___main
mov DWORD PTR [esp], OFFSET FLAT:LC0
call _puts
add esp, 4
xor eax, eax
pop ecx
pop ebp
lea esp, [ecx-4]
ret
.def _puts; .scl 2; .type 32; .endef


Se invece usi il compilatore Borland:


.386p
ifdef ??version
if ??version GT 500H
.mmx
endif
endif
model flat
ifndef ??version
?debug macro
endm
endif
?debug S "test.c"
?debug T "test.c"
_TEXT segment dword public use32 'CODE'
_TEXT ends
_DATA segment dword public use32 'DATA'
_DATA ends
_BSS segment dword public use32 'BSS'
_BSS ends
DGROUP group _BSS,_DATA
_TEXT segment dword public use32 'CODE'
_main proc near
?live1@0:
;
; int main(void){
;
push ebp
mov ebp,esp
;
; puts("CIAO MONDO!");
;
@1:
push offset s@
call _puts
pop ecx
;
; return 0;
;
xor eax,eax
;
; }
;
@3:
@2:
pop ebp
ret
_main endp
_TEXT ends
_DATA segment dword public use32 'DATA'
s@ label byte
; s@+0:
db "CIAO MONDO!",0
align 4
_DATA ends
_TEXT segment dword public use32 'CODE'
_TEXT ends
public _main
extrn _puts:near
?debug D "test.c" 14468 26281
end

nuovoUtente86
04-04-2008, 12:59
No dicevo i file .asm e .s contengono codice assembly ma come mai alcuni compilatori utilizzano un' estensioni e alcuni l' altra?
Con quale comando hai ottenuto la sintassi intel?

variabilepippo
04-04-2008, 13:11
No dicevo i file .asm e .s contengono codice assembly ma come mai alcuni compilatori utilizzano un' estensioni e alcuni l' altra?

Perché ad alcuni programmatori piace il caffè espresso lungo, ad altri quello ristretto al vetro, ad altri quello americano, altri ancora non bevono caffè? :D


Con quale comando hai ottenuto la sintassi intel?

-S -masm=intel

nuovoUtente86
04-04-2008, 13:17
Esisterà qualche motivo nella scelta dell' estensione presumo!Probabilmente dipende dalla piattaforma?!

variabilepippo
04-04-2008, 14:14
Esisterà qualche motivo nella scelta dell' estensione presumo!Probabilmente dipende dalla piattaforma?!


L'estensione è una scelta assolutamente arbitraria, non a caso GNU GCC genera file .s sia sotto Linux, sia sotto tutte le altre piattaforme supportate (nessuno ti vieta di rinominare i file e di assemblarli con un assembler compatibile). Dipende dai "gusti" (vedi la battuta sul caffè) degli sviluppatori del compilatore. Poi se interessano i motivi "storici" per i quali siano state adottate particolari estensioni piuttosto che altre allora dovresti contattare direttamente i team di sviluppo. :)

cdimauro
04-04-2008, 21:24
Perfetto, questo è quello che fa il .NEt
ma questo intervento

sembrava riferirsi all' assembly per .Net e al bytecode come cose diverse.Forse ho inteso male io.
Concettualmente bytecode e assembly sono la stessa cosa: una rappresentazione "astratta" del codice originale, che dev'essere poi ulteriormente "trasformato" per essere interpretato/eseguito dall'architettura target.
L'estensione è una scelta assolutamente arbitraria, non a caso GNU GCC genera file .s sia sotto Linux, sia sotto tutte le altre piattaforme supportate (nessuno ti vieta di rinominare i file e di assemblarli con un assembler compatibile). Dipende dai "gusti" (vedi la battuta sul caffè) degli sviluppatori del compilatore. Poi se interessano i motivi "storici" per i quali siano state adottate particolari estensioni piuttosto che altre allora dovresti contattare direttamente i team di sviluppo. :)
Ai tempi dell'Amiga, gli assemblatori (per Motorola 68000 & derivati) usavano generalmente ".s" come estensione. :cool:

gugoXX
04-04-2008, 21:32
Ai tempi dell'Amiga, gli assemblatori (per Motorola 68000 & derivati) usavano generalmente ".s" come estensione. :cool:

E' vero. Quanto ricordi.
Blitter.s
ftp://ftp.scene.org/pub/mirrors/amigascne/SceneSources/BigTime/blitter.S

cdimauro
05-04-2008, 07:49
E' vero. Quanto ricordi.
Blitter.s
ftp://ftp.scene.org/pub/mirrors/amigascne/SceneSources/BigTime/blitter.S
E quanta inefficienza nel codice di quella routine... :rolleyes:

Già dalle prime righe si capisce che chi l'ha scritto conosceva l'architettura del 68000 all'acqua di rose, e idem per l'hardware dell'Amiga. :muro: