[Powered by Google Translate] ROB BOWDEN: Laten we het hebben over compilers. Tot dit punt, je hebt net getypt up van uw broncode in een aantal bestanden, stuurde ze door deze grote zwarte doos die is Clang, en uit komt uw uitvoerbare bestand dat doet precies wat u schreef in uw broncode. Zo magisch als die is geweest, gaan we aan een nader te nemen kijken naar wat er daadwerkelijk gebeurt wanneer we een dossier samen. Dus wat betekent het om iets samen te stellen? Nou, in de meest algemene zin, het betekent alleen transformeren code geschreven in een programmeertaal naar een andere. Maar meestal als mensen zeggen dat ze samen te stellen iets, ze zeggen dat ze het nemen van het van een hoger niveau programmering taal naar lagere programmeertaal. Dit lijken misschien erg subjectieve termen. Bijvoorbeeld, heb je waarschijnlijk niet denken aan C als een hoge level programmeertaal, maar je compileren. Maar het is allemaal relatief. Zoals we zullen zien, de assemblage-code en uiteindelijk machine code die we naar beneden te compileren is onmiskenbaar een lager niveau dan C. Hoewel we zullen met behulp van Clang in de demonstratie van vandaag, een Veel van de ideeën hier kunnen worden overgedragen naar andere compilers. Voor Clang, zijn er vier belangrijke stappen in de totale compilatie. Dit zijn een, voorbewerking uitgevoerd door de preprocessor, twee, compilatie gedaan door de compiler, drie, assembleren gedaan door de assembler en vier, koppeling gebeurt door de linker. Het verwarrend kan zijn dat een van de substappen van de algemene Clang compilers heet de compiler, maar we krijgen dat. We zullen met behulp van een eenvoudige Hello World programma als voorbeeld gedurende deze video. Laten we eens een kijkje nemen. De eerste stap is voorverwerking. Wat doet de preprocessor doen? In vrijwel elke C-programma die je ooit hebt gelezen of geschreven, je hebt gebruikt regels code die beginnen met een hekje. Ik noem het hash, maar u kunt ook bellen het pond, het aantal ondertekenen, of scherp. Een dergelijke regel is een preprocessor richtlijn. U heeft waarschijnlijk gezien # # define en omvatten voor, maar er zijn verschillende meer dat de preprocessor herkent. Laten we eerst nog # define onze hello world voorbeeld. Laten we nu eens gewoon de preprocessor draaien op dit bestand. Bij het passeren van Clage de-e vlag, je bent de instructie uit te voeren alleen de preprocessor. Laten we eens kijken wat er gebeurt. Het lijkt erop dat Clang net spuugt alles op de opdrachtregel. Met het oog op al deze uitgang op te slaan in een nieuw bestand geheten hello2.c, we voegen> hello2.c op onze opdracht. Laten we nu eens een kijkje op onze voorbewerkte bestand. Whoa, wat is er gebeurd met onze korte kleine programma? Als we gaan helemaal naar de onderkant van dit bestand, we zullen zien een deel van de code die we hebben geschreven. Merk op dat de # define is verdwenen en alle exemplaren van de naam zijn vervangen door wat we de in de # define lijn. Dus wat zijn al deze typedefs en functie verklaringen bovenaan het dossier? Merk op dat de # define niet de enige preprocessor richtlijn die we hadden aangegeven. We hebben ook # include stdio.h. Dus alle van de gekke lijnen zijn eigenlijk gewoon stdio.h gekopieerd en geplakt in de top van dit bestand. Dat is waarom header-bestanden zijn zo nuttig voor de functie verklaringen. In plaats van om te kopiëren en plakken van al van de functie verklaringen u van plan bent over het gebruik van op de top van uw dossier, de preprocessor zal kopieren en te plakken uit de header bestand voor je. Nu dat we preprocessing gedaan, gaan we naar compilatie. De reden dat we noemen deze stap compilatie is, want dit is de stap waar Clang ook werkelijk doet haar compileren van C naar assembly code. Met het oog op zijn Clang een dossier samen tot de montage, maar blijven niet verder, geef het de vlag-S op de opdrachtregel. Laten we eens een kijkje nemen op de vergadering bestand dat is uitgevoerd. Lijkt heel andere taal. Montage-code is zeer processor specifiek. In dit geval, aangezien de CS50 apparaat wordt uitgevoerd op een virtuele x86-processor, is dit x86 assembly code. Zeer weinig mensen schrijven direct in assembler deze dagen, maar elke C-programma die je ooit schrijven wordt getransformeerd naar beneden in de montage. Nogmaals, we noemen deze stap het opstellen van de C in de montage Aangezien we van een hoger niveau naar een lager niveau programmeertaal. Wat maakt de montage lager niveau dan C? Nou, in de montage, zijn wij zeer beperkt in wat we kunnen doen. Er zijn geen of, terwijl het voor is, of lussen van welke aard ook. Maar je kunt bereiken dezelfde dingen die deze controle structuren bieden met behulp van de beperkte activiteiten die assemblage biedt wel. Maar om te zien hoe laag niveau assemblage werkelijk is, laten we gaan nog een stap verder in onze compilatie, assembleren. Het is de assembler de taak om de assembly code te transformeren in object of machine code. Vergeet niet dat de assembler niet doet uitgang montage; Integendeel, het is de montage en de outputs machine code. Machine is de werkelijke 1's en 0's die een CPU kan begrijpen, hoewel we nog steeds een heel klein beetje van het werk links voordat we kunnen draaien ons programma. Laten monteren onze assemblage-code door het passeren van Clang de-c vlag. Laten we nu eens kijken wat er in de verzamelde bestand. Nou ja, betekent dat niet ons ten zeerste helpen. Vergeet niet dat de machine code is de enen en nullen die uw computer kan begrijpen. Dat betekent niet dat het is gemakkelijk voor ons om te begrijpen. Dus precies hoe laag niveau is de montage? Het is bijna identiek aan objectcode. Gaande van assemblage tot object-code is veel meer een vertaling dan een transformatie Daarom kan men de assembler niet beschouwen voert u een werkelijke compiling. In feite, het is vrij eenvoudig om handmatig vertalen van assemblage van de machine code. Kijkend naar de assembly voor een hoofdfunctie, die eerste regel gebeurt overeen te stemmen met hexadecimale 0x55. In binaire, dat is 1010101. De tweede regel gebeurt overeen te komen hexadecimale 0x895. En de volgende, 0x56. Gegeven een relatief eenvoudige tafel, kun je vertalen geheel in de code die machines te kunnen begrijpen. Dus er is een resterende stap in compilatie, dat wordt het koppelen. Koppelen combineert een bos van object bestanden naar een groot bestand dat je daadwerkelijk kunt uitvoeren. Koppelen is erg systeemafhankelijk. Dus de gemakkelijkste manier om Clang te krijgen om gewoon te koppelen object bestanden samen is om Clang een beroep doen op alle bestanden die je wilt met elkaar te verbinden. Als u opgeeft. O bestanden, dan zal het niet opnieuw moet bewerken, compileren, monteren en al uw broncode. Laten we gooien een wiskundige functie in ons bestand, dus we moeten iets te linken inch Laten we nu eens terug te compileren naar object code en noemen Clang op. Oeps. Aangezien wij omvatte een wiskundige functie, moeten we in koppelen de wiskunde bibliotheek met-lm. Als we wilden aan elkaar te koppelen stelletje. O bestanden die we schreef op onze eigen, zouden we gewoon opgeven ze allemaal op de opdrachtregel. De beperking is dat slechts een van deze bestanden moet eigenlijk geef een hoofdfunctie, of anders de resulterende uitvoerbaar zou niet weten waar te beginnen het runnen van uw code. Wat is het verschil tussen het opgeven van een bestand voor een koppeling in met-l en slechts het opgeven van een bestand direct? Niets. Het is gewoon dat Clang gebeurt om precies te weten welk bestand iets als-lm gebeurt om te verwijzen naar. Als je wist dat bestand zelf, kunt u opgeven expliciet. Vergeet niet dat alle-l vlaggen moeten komen aan het einde van uw klant de vraag. En dat is alles wat er is. Als je gewoon Clang draaien op sommige bestanden, dit is wat het is werkelijk te doen. Mijn naam is Rob Bowden, en dit is CS50.