De obicei principal

Ideea de a scrie acest articol mi-a venit atunci când unul dintre colegii mei au fost obligați să se supună un curs inițial de CS la universitatea mea. Am cautat o modalitate de a scrie corecta programul astfel încât să treacă testele, dar nici unul dintre examinările nu au putut intelege cum si de ce functioneaza. Așa că am început să-și amintească trucuri în C, care sunt văzute o singură dată în codul vechi, iar unul dintre ei a fost destul de distractiv. Ideea acestui truc a venit la mine din cauza numelui blogului «principal este, de obicei, o funcție». M-am gândit, „și în ce cazuri nu poate fi funcția principală?“ Hai să aflăm!

Dacă doriți să descărcați codul sursă pentru acest articol, l-am postat aici. Vă rugăm să rețineți că l-am scris pe Linux pe 64 de biți, și va trebui să-l adapteze sub platforma sa.

Îmi place și cred că o mulțime de dezvoltatori, în căutarea unui răspuns la întrebarea după cum urmează. Pasul 1: căutare pe Google. Pasul 2: rândul său, pe fiecare din link-ul corespunzător pe prima pagină. Dacă problema persistă, am schimba o interogare si repeta peste tot din nou. De data aceasta am avut noroc, iar răspunsul a fost găsit la prima căutare pe StackOverflow. În 1984 a câștigat scurt programul IOCCC. principal a fost declarat că: scurt principal [] =. și-l într-un fel a lucrat! Din păcate, a fost scris de o cu totul altă arhitectură și compilator, și nu am fost în stare să-i să adune, pentru a vedea ce face ea, dar, judecând după faptul că a fost doar un set de numere, am putut imagina că au fost bytes compilate într-o matrice cod, care este pur și simplu plasat în memoria locului de principal.

După ce a acceptat teoria că codul acestui program - compilat funcție principală. prezentate sub forma unei matrice, să vedem dacă putem scrie un mic program și repetați acest truc.

Excelent! Ea a lucrat! Aproape ... Deci, lângă obiectivul nostru - pentru a imprima ceva pe ecran. În ceea ce îmi amintesc atunci de asamblare în cod compilat, secțiunea instrucțiuni și secțiunea de date. În secțiunea conține comenzi executabile, dar nu se schimba codul, iar secțiunea de date sunt date variabile care nu pot fi efectuate. În cazul nostru, putem umple doar în codul de funcția principală. așa că tot ce am pus în secțiunea de date este inaccesibil pentru noi. Trebuie să găsim o modalitate de a pune un șir de caractere «Bună ziua lume!» Pentru funcția principală și se referă la ea.

Am început să cred că puteți scrie pentru cel mai mic număr de rânduri. Pentru că am știut ce se va programa pentru Linux pe 64 de biți, am putea apela la scriere de comandă a sistemului. care va aduce ceva pe ecran. Sunt, desigur, am înțeles că el ar putea atunci nu folosi de asamblare, dar în același timp, mă bucur că am primit această experiență. Începeți cu CCG de asamblare built-in nu a fost ușor, dar când am mai mult sau mai puțin obișnuit, lucrurile au mers repede.

La început a fost foarte dificil. Sa dovedit că tot ce am putut afla despre asamblare printr-un motor de căutare, este o sintaxa veche-ovsky Intel, și pentru arhitectura pe 32 de biți. De asemenea, a trebuit să compileze codul pe un sistem pe 64 de biți fără steaguri speciale compilator. Acest lucru înseamnă că nu steaguri și opțiuni de compilator, pași suplimentari linker și un built-in sintaxa GCC ATT. Cea mai mare parte a timpului petrecut pe căutarea de informații cu privire la asamblare pentru sistemele pe 64 de biți! Poate inestetice. Aici am bucurat de cea mai mare parte prin încercare și eroare. Am vrut doar să aducă linia «Bună ziua lume!» Pe ecran folosind built-in de asamblare, de ce este atât de dificil? Pentru cei care doresc să învețe cum să facă acest lucru, am recomanda o privire la aceste site-uri: lista syscall Linux. Introducere în inline Asm. Diferențele între Intel și ATT sintaxei.

În cele din urmă, am început să dovedesc mai mult sau mai puțin distincte asm-cod care chiar a lucrat. Să ne amintim, scopul meu este de a scrie un principal, care este o matrice cu asm-instrucțiuni care să fie afișate pe ecranul «Hello World».

>>> hex_string = "554889E5B801000000BB01000000BE10054000BA0D0000000F05B83C00000031DB0F0548656C6C6F20576F726C64210A5D". decodifice ( "hex")

>>> matrice. array (. hex_string 'B')

array ( 'B'. [72. 137. 229. 85. 184. 1. 0. 0. 0. 187. 1. 0. 0. 0. 190. 16. 5. 64. 0. 186. 13. 0 . 0. 15. 5. 0. 184. 60. 0. 0. 0. 49. 219. 15. 5. 72. 101. 108. 108. 111. 32. 87. 111. 114. 108. 100. 33 . 10 93])

Presupun că dacă bash și unix cunoștințele mele a fost la un nivel mai înalt, aș fi găsit o modalitate de a face un pic mai ușor, dar Google ca răspuns la ceva de genul «hexazecimale funcției compilate» oferă câteva întrebări cu privire la modul de imprimare 16 utilitară benă -richny în diferite limbi. Cu toate acestea, acum avem o serie de numere separate prin virgula care reprezintă funcția noastră. Să încercăm să-l scrie într-un fișier nou și verificați pentru a vedea dacă truc va funcționa. Iată ce sa întâmplat.

articole similare