OSもアプリケーションプログラムもCPUが動かしています。
アプリケーション層のプログラムはOSの作法に則って作られており、高級言語はその作法に則って動くようにコンパイラーが中間言語に変換し、リンカーが対象OS用、対象CPU用のライブラリをソースコードに合わせて組み合わせて実行ファイルを生成します。
OSというのはハードウェアを効率よく利用する為にアプリケーション層とハードウェアの物理層との仲介を行うものと考えてください。
OSが用意した仲介役(API)をプログラムから呼び出すことでUSB接続された様々な機器を利用することが可能。
その仕組みを手っ取り早く理解しやすいのはRS-232Cを利用した通信でしょうか。
シリアル通信としてのRS-232CはWindowsの前から存在し、今ではUSB接続でデバイスドライバーによってCOMポートとして動作します。
COMポートをプログラムで利用するにはRS-232Cそのものです。
VisualStudio等の開発環境下では専用オブジェクトを宣言したり配置することにより利用可能となり、オブジェクトが用意しているクラス関数等を呼び出すことで通信が成立します。
シリアル通信だけでなくTCP/IPによる通信も可能です。TCP/IP通信をプログラミングする為にはTCP/IPに関する知識も絶対に必要となります。
最近、VisualStudioを使用して(必要最低限のことが実現できる)プログラムを作りました。ネットで見つけたサンプルソースを元に自分の目的を実現可能か検証する為のプログラムです。迷惑メール送信プログラムではなくw社内業務システムに組み込んでイベント毎に担当者へ通知する用途としてメールが使えないか・・・というのが切っ掛けです。
.NET Frame Workを利用すると大抵のことは.NETのライブラリとして簡単に利用することが可能です。
最新のOSではハードウェフをプログラムが直接操作することは推奨されていないはずです。
そのため、開発言語で用意されているライブラリを利用したり、デバイスドライバーが用意しているAPIを呼び出したりすることでハードを操作するのが今では一般的だと思います。
それ以前のOSや開発環境では、OSがハングアップするようなバグが頻発。開発中のコーディングミスが原因だったとすると下手するとOSがクラッシュしてOS再インストールから・・・と言うケースも希ですがありました。
ハードを直接操作するという事はハードディスクをいきなりフォーマットすることも可能という事です。
それを利用して悪意のあるプログラム(コンピューターウィルス)にそういうことをされると泣きたくても泣けなかったりします。
セキュリティ向上の為、と言う理由もあるでしょう。
ですから、最近ではハードウェアのことを意識してプログラミングすることもずいぶんと減りました。
で、それら全てに関わっているのはCPUです。
そしてBIOS。
Basic Input Output Systemの頭文字からBIOSと呼ばれます。
BIOSもハードウェアに直結したインターフェイス(I/F)を持っており、OSはそのI/Fを呼び出すことで比較的簡単にM/Bに接続されたハードウェアを利用することが可能となります。
ですので、御質問にあるような関係性というのは今では複雑化されており単純なものではなくなっています。
単純なものとして理解したいのであればRaspberry Piのようなキットを利用すると良いと思います。
パソコンという言葉が生まれる前はボードコンピューターのキットで、CPUやメモリなどを自分でプリント基板に半田付けして、プログラムを16進キーボードから1バイトずつ入力したものです。もう少し遡ると1ビット毎にスナップスイッチがあり、1バイト入力する為に8個のスナップスイッチをON/OFFしてEntryスイッチで登録・・・みたいな気が遠くなることをしていました。
たしかパソコン系雑誌にZ80を使用したゲームコントローラーの自殺記事が掲載されていたことがあります。
解説を読むと、一連の動作の為のシーケンスを開始から終了まで実行したらリセットをかけてもう一度頭から開始するというものでした。
そういう原始的なところから勉強するとCPUとOSの関係性も理解しやすくなると自分なんかは考えるわけですが・・・時間がかかりますね。答えだけを求める人には無駄の極地でしかないでしょう。ですが理解度は天と地ほどの差があると思います。
古いものを理解していれば最新のものもすぐ使えるようになる・・・説明書を見なくてもある程度は使えると思うのですが・・・取説を読むのは大事です。取説を読むことでリスクを予測できるという側面もあると思っています。
お礼
的確にありがとうございます!