- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5
Takym QA
Takym > QA
このページでは低レイヤに関する質問とその回答をまとめています。 下記に該当する質問が無い場合は Slack の #初心者質問相談 チャンネルに訪れてみてください。
回答: あります。
例えば x86 では下記の様な命令があります。
| 命令 | 説明 (概略) | 参考 | 
|---|---|---|
| CMPXCHG8B | レジスタとメモリ上の値を比較し等しければ交換します。 | https://www.felixcloutier.com/x86/cmpxchg8b:cmpxchg16b | 
| CRC32 | 巡回冗長検査します。 | https://www.felixcloutier.com/x86/crc32 | 
| INT3 | デバッグ時に使用されます。 | https://x86.puri.sm/html/file_module_x86_id_142.html | 
| UD2 | 無効命令例外を発生させます。 | https://mudongliang.github.io/x86/html/file_module_x86_id_318.html | 
回答: オペランド制約を意味します。
- 
aは EAX レジスタを表します。
- 
dは EDX レジスタを表します。
- 
Nは8ビット即値の命令エンコーディングを優先する事を表します。- 
IN命令とOUT命令で使用されます。
 
- 
- 
NdはNとdの両方を指定しています。
- Constraints (Using the GNU Compiler Collection (GCC))
- Machine Constraints (Using the GNU Compiler Collection (GCC))
- GCCのインラインアセンブラの書き方 for x86
- GCCのインラインアセンブラの構文について調査
- オペランド制約
- https://github.com/torvalds/linux/blob/3dbdb38e286903ec220aaf1fb29a8d94297da246/arch/x86/include/asm/io.h#L275-L287
これは GCC における仕様です。 Microsoft Visual C のインラインアセンブラの仕様とは異なります。
回答: 区画記述子(セグメント・ディスクリプタ、Segment Descriptor)の属性から決定・判定します。
x86 での区画記述子は下記の書式になります。
| 31...24 | 23 | 22 | 21 | 20 | 19...16 | 15 | 14...13 | 12 | 11...8 | 7...0 | 
|---|---|---|---|---|---|---|---|---|---|---|
| Base 31:24 | G | D/B | L | AVL | Seg. Limit 19:16 | P | DPL | S | Type | Base 23:16 | 
| 31...16 | 15...0 | 
|---|---|
| Base Address 15:00 | Segment Limit 15:00 | 
- 
G(Granularity) - 粒度。0の場合は 1 B 単位で設定し、1の場合は 4 KB 単位で設定する。
- 
D/B(Default operation size) - 既定の制御ビット数。0の場合は16ビット、1の場合は32ビット。
- 
L(64-bit code segment) -1の場合は64ビット。(IA-32e のみ)
- 
AVL(Available for use by system software)
- 
P(Segment present) - セグメントが存在する場合は1、存在しない場合は0。
- 
DPL(Descriptor privilege level) - 特権レベルを0~3で指定する。
- 
S(Descriptor type) -0の場合はシステム、1の場合はコードまたはデータ。
出典:https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html、ページ:Vol. 3A 3-9 下部から Vol. 3A 3-12 上部、参照日:2021/07/11
回答: 属性 __attribute__((packed)) を構造体に付与します。構造体を宣言する前に #pragma pack(1) を指定します。
__attribute__((packed)) を構造体に付与します。- 詳しくは NoAlign をご覧ください。下記の説明は古い情報ですが、記録として残しておきます。
- 下記の様に属性を指定します。
typedef struct _STRUCT_A_ { unsigned int id; unsigned char *name; } __attribute__((packed)) StructA; 
- 
Microsoft Visual C では下記の様に #pragma packを使って記述できます。#pragma pack(1) typedef struct _STRUCT_A_ { unsigned int id; unsigned char *name; } StructA; #pragma pack() 
データ構造アライメントはメモリ上のデータを効率的に配置する為に利用されています。
回答: 環境に依存しますが、デバッガで覗く事ができます。
INT 0xXX 命令にブレークポイントを貼り、デバッガを使ってコードを覗く事ができます。
実機でデバッグを行う場合は専用の機器が必要になる可能性があります。
仮想環境でデバッグを行う場合は QEMU に GDB を接続すれば良いでしょう。
もしくはオープンソースの実装を読む事もできます。
回答: ありますが、難易度は高いです。
BIOS (INT 0x10 命令) を使わずに描画処理を行うには下記の方法が考えられます。
- グラフィックコントローラ、ビデオチップ、GPU 等の仕様書を入手する。
- 仕様書は有料である場合や公開されていない場合もあります。
 
- X Window System 等既存のオープンソースシステムを利用または解析する。
BIOS ROM に保存されているコードの解析は利用規約や著作権に抵触する可能性があります。
回答: UTF-16BE または UTF-32BE 以外の文字コードで保存されている可能性があります。
Unicode では必ずコードポイントと同じ値がファイルに保存される訳では無く、通常は UTF-8、UTF-16、UTF-32 のいずれかに符号化してから保存されます。 「あ」(U+3042)という文字の場合は文字コード毎に下記の様に変換されます。
- 
UTF-8: E3 81 82
- 
UTF-16LE: 42 30
- 
UTF-16BE: 30 42
- 
UTF-32LE: 42 30 00 00
- 
UTF-32BE: 00 00 30 42
C言語の型 wchar_t はワイド文字型であり、どの文字コードを使うかは規定されておらず、環境依存になります。コンパイラやOSなどにより異なります。
上記で挙げた文字コードではない可能性もあります。
どの文字コードが使われるかは適宜確認する必要があります。
回答: 不定値が返却されます。異常な値が入力された場合の動作は未定義です。
異常な値が入力された場合、標準入力ストリームにその値を残したままにしてしまいます。
例えば、下記のコードを実行し「123a」と入力した場合、(2) で入力は行われず、(3) は「123」を出力します。勿論、(1) は「123」を出力します。
#include <stdio.h>
int main(int argc, char *argv[])
{
	int a;
	scanf("%d", &a);
	printf("%d\r\n", a); // (1)
	scanf("%d", &a);     // (2)
	printf("%d\r\n", a); // (3)
	return 0;
}Wikipedia の「Scanf#異常な入力が行われた時の処理」が参考になります。
scanf の内部実装は下記のページが参考になります。
異常な値が入力された場合、正しい値は返却されません。 下記の様に正しい整数値が入力されたかどうか検証する事ができます。
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
	int a;
	cin >> a;
	if (cin.fail()) {
		cout << "Not a number" << endl;
	} else {
		cout << a << endl;
	}
	return 0;
}下記のページが参考になります。
- 
scanf及びcinの動作実験は、こちらのページをご参照ください。
- 上記のコードは GCC で検証しました。VC など他のコンパイラでは異なる動作をする場合があります。
回答: こちらのページを参考にしてください。
(書きかけ...)
回答: OS の仕組みに依りますが恐らく問題ありません。
「はりぼてOS」や「MikanOS」等を参考に開発した OS であれば強制終了しても問題は無いでしょう。 UI 上から電源を切る機能(シャットダウン)がない場合(UI が破損している場合を除く)は殆どの場合は問題無いと考えても良いと思います。 強制終了して PC が壊れる原因としては下記の様な原因が挙げられます:
- 
常にハードディスクを読み書きしている場合
- 強制終了すると、ハードディスクの読み書きが中断され、保存されているデータが壊れる可能性があります。
 
- 
一時ファイルやキャッシュが正しく破棄されない場合
- 終了時に一時ファイルやキャッシュを破棄する必要がある場合、次回起動時にエラーが発生する可能性があります。
 
- 
動作中に設定を変更した場合
- 終了時に変更された設定を整理し保存する様な仕組みになっている場合、次回起動時に変更した設定が失われる可能性があります。
 
- 
プログラムの更新中に終了した場合
- 正しくないプログラムが保存され、誤動作を引き起こす可能性があります。
- または、OS そのものが起動しなくなる可能性もあります。
 
因みに、筆者(@Takym)は Windows 10 で強制終了を行った事がありますが、壊れた事はありません。 強制終了しても壊れない OS の開発に挑戦してみるのも良いと思います。