Bagaimana program dijalankan pada level CPU?

14

Saya tahu ini adalah pertanyaan yang sangat umum. Tetapi saya memiliki sudut pandang yang berbeda dalam pikiran saya. Saya hanya akan mencoba mengartikulasikannya di sini.

Dari apa yang saya tahu, setiap instruksi yang dieksekusi CPU, dalam bahasa mesin dan semua CPU dapat lakukan adalah melakukan beberapa operasi aritmatika berkat ALU dan transistornya (jika kita menggunakan level perangkat keras).

Namun ini lebih mudah untuk diketik daripada memahaminya. Jadi jika semua CPU melakukan penambahan, pengurangan, dll., Lalu bagaimana sebuah program, katakanlah program JAVA yang mengatakan print Hello World, dijalankan dengan operasi aritmatika ini?

Maksud saya bagaimana program ini diubah menjadi sesuatu yang hanya merupakan tambahan untuk CPU?

PS Jika pertanyaan ini tidak berlaku untuk situs web ini maka saya mohon maaf.

-----Bagian kedua-----

Baik. Terima kasih untuk semua yang menjawab ini dengan cepat dan dengan antusiasme ini. Saya pikir lebih baik memodifikasi pertanyaan saya daripada pergi dan berkomentar untuk semua jawaban dan bertanya lagi.

Jadi begini.

Pertama, semua telah menjawab secara khusus contoh Hello World. Ini salah saya. Saya seharusnya menyimpan obat generik ini. Contoh Hello world mempertanyakan perangkat output dan bagaimana pemrosesannya tidak hanya terbatas pada CPU, yang seharusnya diangkat dalam jawaban Anda.

Juga banyak dari Anda yang menyadari bahwa CPU melakukan lebih dari sekedar penambahan. Saya setuju dengan itu. Saya hanya tidak menulis itu dan menganggapnya sepenuhnya. Dari apa yang saya mengerti, inilah prosesnya:

  1. membaca instruksi dari memori (menggunakan data dan alamat bus dan program counter)

    1. menyimpan data dalam register di dalam CPU
    2. Sekarang ALU melakukan operasi aritmatika, tentu saja setelah men-decoding instruksi, atau mengambil lompatan jika itu instruksi jika suka
    3. Dan kemudian berkomunikasi dengan sumber daya lain jika diperlukan seperti dengan perangkat output dan sebagainya. Proses di luar ini sepele untuk saat ini.

Jadi pada langkah 3 di mana CPU mendekode instruksi dan memutuskan untuk melakukan operasi aritmatika (di sini kita mengasumsikan bahwa tidak ada operasi lain yang harus dilakukan seperti lompati instruksi saat ini .. karena operasi aritmatika banyak dilakukan..jadi kita akan tetap berpegang pada itu ) Di sinilah visualisasi saya berakhir. Bagaimana instruksi dari program saya hanyalah operasi aritmatika untuk CPU. Itu melakukan operasi aritmatika dan instruksi yang melayani tujuannya.

Saya harap saya membuat diri saya jelas kali ini.

PS Saya mengambil asumsi besar di sini bahwa ALU tidak hanya terbatas pada operasi aritmatika aktual yang kami lakukan dalam program kami, melainkan mengeksekusi semua instruksi, yang sekarang dalam bentuk biner, dengan menambahkan atau mengurangi dll untuk menghasilkan hasil yang dimaksudkan untuk menghasilkan. Jika saya salah di sini daripada jawaban di bawah dengan benar menjawab pertanyaan saya.

pengguna2827893
sumber
Saya mengerti bahwa kompiler mengubah program menjadi bahasa mesin. Saya hanya tidak bisa memvisualisasikan program sebagai operasi aritmatika. Meskipun jika program itu sendiri adalah tentang menambahkan dua angka maka itu bisa dimengerti tetapi sebaliknya tidak .. tapi :)
user2827893
1
Mungkin Anda harus mulai melihat set instruksi CPU yang sebenarnya, misalnya yang sangat sederhana seperti MC6502, Z80 ... kemudian lihat bahwa ada instruksi akses memori, instruksi pemrosesan data, cabang ... Anda kemudian dapat menebak bagaimana mereka bisa dikombinasikan untuk mengimplementasikan algoritma apa pun.
TEMLIB
3
CPU pasti bisa melakukan lebih dari sekedar penambahan. Sangat penting untuk menyebutkan bahwa CPU dapat melakukan perbandingan dan lompatan.
Theodoros Chatzigiannakis
1
Anda (tampaknya) masih dengan tegas menolak untuk melihat IF (mengambil keputusan) dan MOVE (membaca dan menyimpan data), Pemrograman adalah 99% IF dan MOVE. Aritmatika dapat diabaikan. Contoh pertama Anda (Hello world) tidak memiliki aritmatika sama sekali.
edc65
1
1. Saya pikir Anda akan lebih mungkin mendapatkan jawaban yang baik jika Anda mengajukan pertanyaan baru dengan kebingungan baru Anda, daripada mengedit pertanyaan ini untuk mengubah apa yang Anda tanyakan. Anda mendapat jawaban yang bagus untuk pertanyaan awal Anda, dan pertanyaan awal Anda sepertinya bisa berdiri sendiri, jadi mengapa tidak menghapus hasil edit dan mengajukan pertanyaan baru? 2. Yang mengatakan, saya tidak bisa mengerti bagian baru. Apa sebenarnya pertanyaan Anda tentang bagian yang baru? Ketika Anda mengatakan "ini adalah di mana visualisasi saya berakhir", maksudmu kau tidak mengerti langkah 3, atau Anda tidak mengerti langkah 3? Jika Anda melakukannya, apa yang tidak Anda mengerti?
DW

Jawaban:

7

Anda dapat mencoba mengambil program sederhana dan mengompilasinya ke kode mesin asli. (Java biasanya mengkompilasi ke kode JVM, tetapi Andrew Tennenbaum memiliki buku di mana ia menjelaskan cara mendesain CPU yang berjalan secara native, jadi itu akan dilakukan.) Pada GCC, misalnya, Anda memberikan kompiler -Ssaklar.

Ini akan memberi tahu Anda bahwa segala sesuatu yang rumit, seperti I / O, diimplementasikan dengan memanggil sistem operasi. Meskipun Anda dapat mengunduh sumber ke kernel Linux dan melakukan hal yang sama dengannya, apa yang terjadi di bawah tenda adalah: semuanya memanipulasi keadaan memori komputer, misalnya daftar proses yang berjalan, atau berbicara dengan perangkat keras dengan menggunakan alamat memori khusus yang mengendalikannya atau menggunakan instruksi CPU khusus seperti indan outpada x86. Namun, secara umum, hanya program khusus yang disebut driver perangkat yang akan berbicara dengan perangkat keras tertentu, dan OS akan mengirimkan permintaan untuk menggunakan perangkat keras ke driver yang tepat.

Khususnya, jika Anda mencetak, "halo, dunia!" kompiler Anda akan mengubahnya menjadi satu set instruksi yang memuat string ke lokasi tertentu (misalnya, memuat alamat string dalam memori ke %rdiregister) dan memanggil fungsi perpustakaan dengan callinstruksi tersebut. Fungsi pustaka ini mungkin menemukan panjang string dengan loop, kemudian memanggil system callwrite()untuk menulis jumlah byte dari string ke file deskriptor nomor 1, yang merupakan output standar. Pada titik itu, OS mencari tahu apa proses itu 'file nomor 1 dan memutuskan apa artinya menulis. Jika menulis ke output standar dicetak pada layar Anda, akan ada beberapa proses seperti menyalin byte ke buffer, yang kemudian dibaca oleh program terminal Anda, yang memberitahu sistem windowing huruf mana yang harus diletakkan di mana dalam font apa. Sistem windowing memutuskan dengan tepat seperti apa tampilan itu, dan memberi tahu driver perangkat untuk meletakkan piksel pada layar, yang dilakukannya dengan mengubah memori video.

Davislor
sumber
Terima kasih @Lorehead. Penjelasan ini terlihat bagus sebagai contoh Hello world.
user2827893
5

CPU Anda sendiri bodoh, seperti yang Anda tahu. Tetapi ada mikrokosmos chip perangkat keras di sekitarnya. Anda memiliki instruksi yang memungkinkan Anda mengatur satu baris CPU ke level tinggi yang ditransfer ke chip lain. Chip perangkat keras itu memonitor garis dan berkata: "Hei, jika garis ini tinggi, maka saya melakukan sesuatu dengan beberapa garis lainnya."

Untuk mempermudah ini, garis-garis ini dikelompokkan bersama. Beberapa digunakan untuk alamat perangkat, ada yang digunakan untuk mentransfer data untuk alamat tersebut dan yang lain lagi hanya "Bung, ada sesuatu yang penting terjadi di dalam chip saya" baris.

Pada akhirnya, CPU Anda hanya memberi tahu beberapa chip lain untuk cantik silakan memodifikasi sinyal ke monitor sehingga terlihat seperti "Hello World".

Google menggambar tampilan 7-segmen. Ini memiliki kabel, yang akan membuat segmen menyala jika Anda menerapkan tegangan ke sana. Jika sekarang Anda menyambungkan satu jalur output CPU dengan satu baris layar 7-segmen, layar akan menyala. Bukan CPU yang menyebabkan LED menyala, melainkan hanya memberi tegangan pada saluran, tetapi beberapa perangkat keras lain mungkin melakukan hal-hal bagus karena itu.

Jika CPU Anda sekarang menetapkan semua baris untuk H ke tinggi, 7-segmen akan menampilkan H, meskipun H bukan angka yang akan ditambahkan atau dikurangkan oleh CPU.

Sekarang, jika semua layer setuju dengan apa yang diperlukan untuk membuat 7-segment-display H (set 5 baris spesifik ke tinggi), kompiler Java dapat membuat kode untuk membuatnya menampilkan H. Ini tentu saja agak merepotkan - sehingga layer-layer mulai untuk abstrak. Lapisan terendah akan dimulai dengan: "Yo, ada seperti 26 huruf, mari kita tentukan angka untuk setiap huruf - bagaimana kalau kita berikan huruf 'H' angka '72'? Lalu Anda bisa memberi tahu saya" Tampilan huruf 72 ", alih-alih "Tetapkan baris 309 tinggi, setel baris 310 tinggi, setel baris 498 tinggi, setel baris 549 tinggi, setel baris 3 tinggi". Maka setiap lapisan mulai informasi abstrak, cara mencapai hasil tertentu, sehingga Anda tidak perlu untuk peduli tentang mereka.

Jadi ya, itu meringkas ke pemetaan angka atau bit, CPU benar-benar dapat memproses, untuk arti bahwa semua orang dalam rantai setuju.

John Hammond
sumber
3

Di perguruan tinggi sebagai bagian dari program gelar CS, saya mempelajari contoh tambahan bahasa transfer register yang mendefinisikan CPU. Saya terinspirasi untuk mengambil pandangan berbeda dan menulis simulator yang menerima notasi seperti definisi, dan menerbitkannya di Embedded Systems Programming (edisi Maret 1989) sebagai cara untuk menjawab pertanyaan yang sama seperti yang Anda tanyakan, memungkinkan orang untuk membangun pemahaman intuitif mereka tentang hal-hal seperti itu.

Di kelas, kami melanjutkan untuk menyaring notasi resister-transfer ke gerbang logika aktual pada register! Itu menulis sendiri: lihat segala sesuatu yang telah mendaftarkan 'A' sebagai tujuan, dan kode A = (case1) atau (case2) ... dan yang dinyatakan sebagai jumlah-produk-produk atau produk-of-jumlah bentuk normalisasi.

Hanya pada akhir kursus saya belajar bahwa ini adalah CPU nyata: PDP-8 jika saya ingat dengan benar.

Hari ini Anda bisa memberi makan diagram gerbang ke dalam chip array logika yang dapat diprogram.

Itulah intinya: register diatur dengan hasil gerbang AND dan OR yang mengarah kembali ke register lain. Salah satu nilai yang dimasukkan adalah nilai opcode.

Jadi bayangkan: A: = (opcode == 17 & X + Y) | (opcode == 18 & X + Z) | ...

CPU modern lebih rumit, dengan jaringan pipa dan bus, tetapi subunit individual seperti ALU tunggal bekerja seperti itu.

JDługosz
sumber
2

Anda sedang mempertimbangkan CPU di sini, tetapi ada komponen lain yang terlibat saat menjalankan 'Hello World': tampilan!

Untuk CPU, nilai dalam memori hanyalah angka yang direpresentasikan sebagai jumlah bit yang diberikan (0 dan 1).

Bagaimana itu berubah menjadi huruf di layar adalah cerita lain: layar juga memiliki memori. Memori ini (memori grafis) dipetakan ke 'piksel' pada layar. Setiap piksel dikodekan dengan nilai: jika ini merupakan tampilan monokrom yang sangat mendasar, nilainya hanya intensitas, untuk warna yang ditampilkan nilainya adalah kombinasi Merah Hijau dan Biru (RGB) yang dapat disandikan dengan berbagai cara.

Jadi, ketika CPU 'menulis' nilai yang diberikan ke memori tampilan, piksel menyala. Untuk benar-benar menulis surat, orang perlu menerangi banyak piksel. Biasanya komputer akan memiliki set karakter (sebenarnya beberapa) yang didefinisikan dalam sistem operasinya. (membuat abstraksi dari 'font' itu sendiri, yang memetakan definisi seperti apa setiap huruf pada layar)

Jadi, ketika kode dikompilasi, itu mencakup segala macam hal yang berasal dari pustaka OS, termasuk font / char set ini dll. Yang memungkinkan CPU mengetahui apa yang harus ditulis di mana dalam memori grafis. (Ini cukup rumit tapi itu ide umum: kompiler menyertakan lebih banyak kode daripada apa yang ada dalam kode 'hello world' Anda sendiri, melalui perpustakaan yang diimpor)

Pada akhirnya, ada banyak hal terjadi seperti yang Anda duga, tetapi Anda tidak harus menulis semua kode itu.

MrE
sumber
1

Inilah pendekatan formal untuk pertanyaan Anda dari bidang ilmu komputer teoretis.

Pada dasarnya, kita dapat mendefinisikan pemetaan antara model komputasi CPU dan mesin turing. Ada bukti teoritis bahwa himpunan semua program mesin turing yang dapat dibayangkan (dan oleh karena itu semua program yang dapat dibayangkan dieksekusi pada CPU) dapat dihitung tanpa batas. Ini berarti bahwa kami dapat mengidentifikasi setiap program dengan bilangan asli, termasuk program yang akan memperluas bilangan asli ke mesin turing .

Seperti yang telah Anda ketahui bahwa hampir semua hal yang dilakukan CPU adalah perhitungan pada bilangan asli dalam representasi biner, Anda dapat beralasan bahwa CPU dapat menjalankan setiap program yang dapat dibayangkan.

Catatan: Ini terlalu disederhanakan, tetapi, menurut saya, memberikan intuisi yang bagus.

Kevin Dreßler
sumber
1

Yang mungkin membantu adalah mengalihkan pemikiran Anda dari "melakukan aritmatika." Jika Anda benar-benar mencoba menggali apa yang dilakukan komputer di bawah tenda untuk mencetak "Hello World" yang terbaik untuk berpikir satu tingkat lebih rendah. "Status" komputer dapat digambarkan sebagai satu set bit, disimpan oleh sakelar transistor yang hidup atau mati (atau kapasitor yang terisi atau tidak terisi). Komputer memanipulasi bit-bit itu sesuai aturan. Cara komputer diizinkan untuk memanipulasi bit tersebut ditulis ke CPU dalam bentuk transistor yang melakukan pekerjaan mengubah bit dari 0 menjadi 1, atau 1 ke 0.

Ketika ALU "melakukan aritmatika," apa yang sebenarnya berarti adalah bahwa ia mengubah keadaan komputer dengan cara yang konsisten dengan aturan aritmatika kita. Yang dilakukannya hanyalah mengubah beberapa bit. Itu artinya di balik perangkat lunak yang menjelaskan mengapa kita harus menganggapnya sebagai penambahan atau pengurangan yang. CPU tidak "tahu" apa yang dilakukannya. Itu hanya berubah dari satu negara ke negara lain, dan itu saja (setidaknya sampai Skynet mengambil alih).

Ketika Anda memikirkannya seperti itu, instruksi yang lebih rumit seperti instruksi "lompatan" tidak berbeda. Yang dilakukannya hanyalah mengubah beberapa bit. Dalam hal ini kebetulan mengubah bit yang kita tahu berarti lokasi instruksi selanjutnya untuk dieksekusi. CPU tidak "tahu" ini, tapi kami tahu. Jadi kami menggunakan instruksi yang mengubah bit-bit itu untuk "melompat" dari satu tempat ke tempat lain dalam kode kami.

IO juga tidak berbeda, hanya mengubah bit. Satu-satunya perbedaan kecil adalah bahwa bit-bit tersebut terhubung ke transistor yang akhirnya mengarah pada menerangi karakter pada layar Anda. Jika saya dapat mengingat kembali beberapa dekade ketika "Hello World" sebenarnya sederhana, ada ruang memori di mana, jika Anda menulis bit ke dalamnya yang sesuai dengan karakter ASCII untuk "Hello World," karakter-karakter tersebut akan diberikan langsung ke layar. Sekarang ini sedikit lebih rumit, karena kami memiliki kartu grafis dan sistem operasi yang mengacaukannya, tetapi ide dasarnya sama. Anda memiliki satu set transistor yang aktif atau tidak aktif, yang dihubungkan ke sirkuit untuk menampilkan piksel pada layar. Kami mengatur yang tepat, dan sepertinya "Hello World" muncul di layar.

Kebingungan hanyalah masalah sintaks vs semantik. Perilaku "setengah ditambahkan" atau "ditambahkan penuh" dalam ALU adalah sintaksis. Ini mendefinisikan bit apa yang akan keluar ketika Anda memasukkan bit. Semantiknya adalah konsep kemampuan untuk melakukan penambahan. Anda dan saya sadar bahwa ALU dapat "melakukan penambahan," tetapi untuk benar-benar memahami apa yang terjadi di bawahnya, Anda harus ingat bahwa ALU hanya memanipulasi bit dan byte dari sintaks.

Cort Ammon - Pulihkan Monica
sumber
0

CPU bekerja seperti ini:

  • ambil instruksi saat ini, tambahkan pointer "instruksi saat ini".

  • memecahkan kode itu (mis. cari tahu apa instruksi ini memberitahu CPU untuk melakukan)

  • jalankan itu (lakukan apa yang dikatakan instruksi) - pointer instruksi saat ini dapat dimodifikasi jika instruksi itu seperti "lompatan".

  • Ulangi selamanya

CPU modern lebih kompleks dan mencoba untuk sangat tumpang tindih dan bahkan memprediksi bagian dari proses itu (misalnya mulai mengeksekusi sementara 10 instruksi lainnya sedang decoding sementara CPU mengambil jauh di depan pointer "instruksi saat ini" untuk menjaga "jalur pipa" penuh), tetapi proses dasarnya benar-benar sama.

Ada banyak jenis instruksi, contoh dari sebagian besar dari mereka adalah:

  • "Pindahkan" instruksi. Ini dapat menyalin X ke X lain, di mana X adalah memori (RAM), register, atau alamat dalam ruang I / O jika CPU mendukung gagasan semacam itu.

  • Instruksi manipulasi tumpukan, termasuk pop ke register, register push pada stack, dll. Ini adalah kasus khusus dari instruksi "pindah" yang menggunakan dan memperbarui register "stack pointer".

  • Instruksi yang melakukan operasi matematika, baik antara dua register atau memori dan register. Instruksi ini secara otomatis memengaruhi register bendera. Salah satu bendera tersebut adalah bendera "nol" yang ditetapkan jika hasilnya nol, yang lain adalah bendera "negatif" yang ditetapkan jika bit paling signifikan dari hasil ditetapkan. Mungkin ada yang lain tergantung pada CPU.

  • Kasus khusus operasi matematika adalah instruksi perbandingan, yang sama dengan pengurangan, tetapi hasilnya tidak disimpan. Bendera masih terpengaruh.

  • Ada instruksi cabang yang melompat ke alamat memori JIKA bendera tertentu diatur. Ingat bendera "nol" yang disebutkan di atas? Ini juga berfungsi sebagai bendera "jika sama", sehingga Anda melihat instruksi seperti BEQpada banyak CPU yang sebenarnya bercabang jika bendera "nol" diatur.

  • Instruksi yang melakukan operasi logis (DAN, ATAU, TIDAK), bit bergeser, dan bit uji. Mereka dapat mempengaruhi bendera seperti instruksi matematika tergantung pada CPU.

  • Instruksi yang melompat tanpa syarat.

  • Instruksi yang melompat dan menyimpan alamat kembali di stack ("panggilan"), dan instruksi lain yang mengeluarkan alamat dari stack ("kembali").

  • Instruksi khusus seperti yang menghentikan CPU, mengidentifikasi CPU, atau memanggil penangan interupsi.

  • "No Operation" - hampir semua CPU memiliki instruksi "no-op" yang hanya menghabiskan siklus dan bergerak.

Ini benar-benar hanya sebuah contoh, ada CPU dengan jenis instruksi yang lebih sedikit dan CPU dengan lebih banyak.

Intinya adalah untuk menggambarkan bahwa ada banyak jenis instruksi selain instruksi matematika di CPU. Segala sesuatu dalam bahasa tingkat tinggi dipecah menjadi jenis operasi di atas dan hanya beberapa dari mereka yang akan menjadi instruksi tipe matematika atau ALU.

LawrenceC
sumber