diff --git a/README.md b/README.md index 03caad5..5905cb6 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# CHANGEME +# information-processing-1_2nd-class diff --git a/assets/prog1_output.png b/assets/prog1_output.png new file mode 100644 index 0000000..8444eb1 Binary files /dev/null and b/assets/prog1_output.png differ diff --git a/assets/prog2_output.png b/assets/prog2_output.png new file mode 100644 index 0000000..6d7c430 Binary files /dev/null and b/assets/prog2_output.png differ diff --git a/assets/prog3_output.png b/assets/prog3_output.png new file mode 100644 index 0000000..ccfce11 Binary files /dev/null and b/assets/prog3_output.png differ diff --git a/assets/prog4_output.png b/assets/prog4_output.png new file mode 100644 index 0000000..834b578 Binary files /dev/null and b/assets/prog4_output.png differ diff --git a/document.yaml b/document.yaml index 7c67f8c..aa41121 100644 --- a/document.yaml +++ b/document.yaml @@ -1,18 +1,18 @@ doc_class: nitreport -title: Insert Title Here +title: 第2回課題 author: - name: 高専 太郎 - student_id: 0000-01 + name: 柴田 健琉 + student_id: "15 (2年生)" date: year: 令和7年 - month: aa月 - day: bb日 + month: 04月 + day: 17日 -school_name: abc高専 -department: 一般科 -subject: 〇〇概論 -professor: □□教員 +school_name: 岐阜工業高等専門学校 +department: 電子制御工学科 +subject: 情報処理I +professor: 岡崎 憲一 page_config: include_cover_page: true @@ -21,6 +21,10 @@ page_config: show_compiled_time: true sections: - - { path: 'section/introduction.tex', newpg: true } - - { path: 'md-out/test.tex', newpg: false } - + - { path: 'section/introduction.tex', newpg: false } + - { path: 'section/syntax.tex', newpg: false } + - { path: 'section/program-1.tex', newpg: false } + - { path: 'section/program-2.tex', newpg: false } + - { path: 'section/program-3.tex', newpg: false } + - { path: 'section/program-4.tex', newpg: true } + - { path: 'section/appendix.tex', newpg: true } diff --git a/main.tex b/main.tex new file mode 100644 index 0000000..1376f12 --- /dev/null +++ b/main.tex @@ -0,0 +1,40 @@ +\documentclass{class/nitreport} + +\reporttitle{第2回課題} +\reportauthor{柴田 健琉} +\studentid{15 (2年生)} +\reportdate{令和7年}{04月}{17日} +\schoolname{岐阜工業高等専門学校} +\department{電子制御工学科} +\subject{情報処理I} +\professor{岡崎 憲一} + +\pagenumbering{roman} + +\begin{document} + \coverpage + + \tableofcontents + \newpage + \pagenumbering{arabic} + + \input{section/introduction.tex} + + \input{section/syntax.tex} + + \input{section/program-1.tex} + + \input{section/program-2.tex} + + \input{section/program-3.tex} + + \input{section/program-4.tex} + \newpage + + \input{section/appendix.tex} + \newpage + + \printbibliography + + \compiledTime +\end{document} \ No newline at end of file diff --git a/output/main.pdf b/output/main.pdf new file mode 100644 index 0000000..d83da00 Binary files /dev/null and b/output/main.pdf differ diff --git a/programs/demo.c b/programs/demo.c new file mode 100644 index 0000000..34f7feb --- /dev/null +++ b/programs/demo.c @@ -0,0 +1,6 @@ +void main(void) { + int a; + a = 255; + + return; +} diff --git a/programs/prog1.c b/programs/prog1.c new file mode 100644 index 0000000..8747ff6 --- /dev/null +++ b/programs/prog1.c @@ -0,0 +1,6 @@ +#include + +int main(void) { + printf("C言語"); + return 0; +} diff --git a/programs/prog2.c b/programs/prog2.c new file mode 100644 index 0000000..6de36e4 --- /dev/null +++ b/programs/prog2.c @@ -0,0 +1,9 @@ +#include + +int main(void) { + printf("C\n"); + printf("言\n"); + printf("語\n"); + + return 0; +} diff --git a/programs/prog3.c b/programs/prog3.c new file mode 100644 index 0000000..d3e0001 --- /dev/null +++ b/programs/prog3.c @@ -0,0 +1,10 @@ +#include + +int main(void) { + printf("情\n"); + printf(" 報\n"); + printf("  処\n"); + printf("   理\n"); + + return 0; +} diff --git a/programs/prog4.c b/programs/prog4.c new file mode 100644 index 0000000..0eecf67 --- /dev/null +++ b/programs/prog4.c @@ -0,0 +1,11 @@ +#include + +int main(void) { + int y = 2007; + int m = 8; + int d = 7; + + printf("柴田健琉の生年月日の和は%dです。\n", y+m+d); + + return 0; +} diff --git a/references.bib b/references.bib index bc328a4..82a2745 100644 --- a/references.bib +++ b/references.bib @@ -1,9 +1,34 @@ -@online{example, - title = {Example Entry}, - author = {Inc., Example}, - organization = {Example, Inc.}, - url = {https://www.example.com}, - year = {1970}, - month = {01}, - urldate = {1970-01-01} +@online{xiny, + title = {Learn C in Y Minutes}, + author = {Bard, Adam and Goretity, Árpád and Trzebiatowski, Jakub and Scannadinari, Marco and Ferguson, Zachary and himanshu and Li, Joshua and Chirila, B., Dragos and Bittencourt, de, P. Heitor}, + translator = {健琉, 柴田}, + language = {japanese}, + url = {https://learnxinyminutes.com/ja/c/}, + year = {2025}, + month = {03}, + urldate = {2025-04-17} +} +@online{cppref_decl, + title = {Declarations}, + author = {Cubbi and Newatthis and Tekne and Fruderica and Mission, Space and YexuanXiao}, + url = {https://en.cppreference.com/w/c/language/declarations}, + year = {2025}, + month = {01}, + urldate = {2025-04-17} +} +@online{cppref_printf, + title = {printf, fprintf, sprintf, snprintf, printf\_s, fprintf\_s, sprintf\_s, snprintf\_s}, + author = {Eendy and P12bot and P12 and Newatthis and Cubbi and Oli and LittleFlower and D41D8CD98F and Mission, Space and Traceon and YexuanXiao and Yaossg}, + url = {https://en.cppreference.com/w/c/io/fprintf}, + year = {2025}, + month = {01}, + urldate = {2025-04-17} +} +@online{gcc_man, + title = {Top (Using the GNU Compiler Collection(GCC))}, + author = {Contributors of GCC}, + url = {https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/}, + year = {2024}, + month = {07}, + urldate = {2025-04-17} } diff --git a/section/appendix.tex b/section/appendix.tex new file mode 100644 index 0000000..4d05670 --- /dev/null +++ b/section/appendix.tex @@ -0,0 +1,93 @@ +\appendix +\section{付録} + +\subsection{Deep Dive - 変数の舞台裏} + +\ref{var_decl_def}節にてプログラムが値の種類を判別するためにコンパイラが型情報に基づいて読み出すべきビット長を実行ファイルに書き込まれると書いたが、実際はどうであろう。 +ここではコンパイラの生成物である実行ファイルをアセンブリに分解して検証していく。なお、この付録を読むのに特別な知識は必要なく、必要に応じて説明する。 + +まずは検証用のソースコードを用意する。今回は以下の物を用意した: + +\defaultlistingstyle +\lstinputlisting[language=C,title={検証用コード}]{../programs/demo.c} + +なお、実行環境は\ref{exec_env}節のものとする。 + +このコードをコンパイルするにあたって、解読を容易にするために少しフラグを変更する必要がある。 +Linuxでの\texttt{gcc}コンパイラは特に指定されていなければコンパイラの機能を使用するための\texttt{libgcc}と\texttt{libc}というC言語の標準的な関数(\texttt{printf}, etc.)などが宣言・定義されたライブラリをリンクします。 +これによりソフトウェアの日常的な機能の再開発を避けれるが、人間が読めるアセンブリに直すとその部分のコードが析出してしまい、目的のコードが埋もれてしまう。 +なので、これらライブラリの自動リンクをやめる必要がある。そこで今回は\texttt{-nostdlib}フラグと\texttt{-nolibc}フラグを追加する。\cite{gcc_man} + +最近のコンパイラは非常に賢く、無意味なコードを取り除いて最適化しようとする。 +だが今回の検証用コードはただ単に変数を宣言・定義するだけで、実際に使用されないのでそのままではコンパイラに無意味と見なされ、勝手に変数の宣言・定義のコードを削除してしまう。 +なのでここにコンパイラによる最適化を無効にするために\texttt{-O0}フラグも追加する。\cite{gcc_man} + +最終的なコンパイルコマンドはこのようになる: + +\begin{center} + \begin{verbatim} + gcc -Wall -nostdlib -nolibc -O0 demo.c -o demo + \end{verbatim} +\end{center} + +上記のコマンドを実行するとリンカからエントリーポイント:プログラムの始まり、が定義されていないとエラーを吐くが解読に問題はないのでそのままでよい。 + +次に生成物である\texttt{demo}をデコンパイル(実行ファイルからアセンブリに戻す作業)を行うためにGNU Binutils\footnote{\url{https://www.gnu.org/software/binutils/}}の\texttt{objdump}を利用する。 + +\newpage + +以下がデコンパイルコマンドとなる: + +\begin{center} + \begin{verbatim} + objdump -Mintel -d demo + \end{verbatim} +\end{center} + +このコマンドの\texttt{-Mintel}フラグはデコンパイル時にアセンブリを私が個人的に読みやすいIntel記法で表記すると\texttt{objdump}に命令できる。 + +上記のコマンドを実行すると次のような出力になる: + +\begin{center} + \begin{verbatim} + +demo: ファイル形式 elf64-x86-64 + +セクション .text の逆アセンブル: + +0000000000401000
: + 401000: 55 push rbp + 401001: 48 89 e5 mov rbp,rsp + 401004: c7 45 fc ff 00 00 00 mov DWORD PTR [rbp-0x4],0xff + 40100b: 90 nop + 40100c: 5d pop rbp + 40100d: c3 ret + \end{verbatim} +\end{center} + +これで\texttt{demo}のデコンパイル結果が出た。\footnote{コンパイル時に\texttt{-nostdlib -nolibc}を指定しないとデコンパイル結果が100行以上になる。} + +このアセンブリの口語訳は以下となる: + +\begin{itemize} + \item \texttt{rbp}レジスタ(CPU内にあるごく小さな変数)の内容をスタック(メモリ上にある最初に入れたデータは最後に出る仕組みを持つデータ保持の構造)の最上部に積む。 + \item \texttt{rsp}レジスタの内容を\texttt{rbp}レジスタに書き込む。 + \item 16進数値\texttt{0xff}(10進数で255)を\texttt{rbp}レジスタの内容から\texttt{0x4}を引いたアドレス(メモリ上の場所を表す住所のような数値)が指している場所に書き込む。 + \item なにもしない。 + \item スタックの最上部にある値を取り、それを\texttt{rbp}レジスタに読み込む。 + \item 呼び出し元の関数に制御を戻す。 +\end{itemize} + +\texttt{rbp}レジスタは主に関数内でのみ有効なローカル変数を格納するレジスタである。 +また、\texttt{rsp}レジスタはスタックポインタといい、現在実行されている関数に関するデータの読み書きに使用される。 + +今回の例では、まず\texttt{rbp}レジスタの内容をスタックに退避させ、現在のスタックポインタが指しているアドレスを\texttt{rbp}レジスタにコピーする。 +次に、\texttt{rbp}が指しているアドレスから4つ分移動させる。 +この時の4は単位が1バイトであるため$4*8=32$ビット分の空を確保している。 +これはまさに宣言そのもので、\texttt{int}型は32ビットのサイズを持つのでちゃんと当てはまる。 +更にこの空いた場所に\texttt{movl}命令を使用して16進数値\texttt{0xff}、10進数の255を移動させている。 +これが定義であり、宣言した場所に値を代入するというC言語の\texttt{a = 255;}と一致する。 + +\newpage + +以上より、\ref{var_decl_def}節で示した値の種類の判別にビット長を実行ファイルに埋め込むということがらが実証された。 diff --git a/section/introduction.tex b/section/introduction.tex index 6347545..c3523ea 100644 --- a/section/introduction.tex +++ b/section/introduction.tex @@ -1,67 +1,13 @@ \section{はじめに} -Start Writing! +\subsection{実行環境}\label{exec_env} -Use lualatex + biber to compile. +この課題のプログラムは以下の環境で動作することが確認されている: -Test Bib\cite{example} - -いろはにほへと ちりぬるを - -{\gtfamily \sffamily \LaTeX で自由な組版を。} - -{\gtfamily \sffamily Write freely with \LaTeX{}.} - -{\ttfamily LaTeX shall be free forever!} - -\defaultlistingstyle - -\begin{lstlisting}[language=C, caption=Basic Hello World] -#include - -int square(int n) { - return n*n; -} - -int main(int argc, char** argv) { - char* msg = "Hello World"; - int x = 3; - int y = square(x); - printf("%s\n", msg); - printf("f(x) = x^2; x: %d, y: %d\n", x, y); - return 0; -} -\end{lstlisting} - -\begin{displaymath} - \int_{a}^{b} f(x) \,dx = F(b)-F(a) -\end{displaymath} - \begin{itemize} - \item C - \item Python - \item Javascript - \item Rust - \item Haskell + \item OS: Arch Linux + \item CPU アーキテクチャ: \lstinline[columns=fixed]{x86_64} + \item Cコンパイラ: \lstinline[columns=fixed]{gcc (GCC) 14.2.1 20250207} + \item Cコンパイラオプション: \lstinline[columns=fixed]{-Wall <ソースコード名> -o <プログラム名>}\footnote{\texttt{-Wall}はコンパイル時に「凡ミス」や書式に関する全ての警告を表示するフラグである。} \end{itemize} -\begin{enumerate} - \item lualatex .tex - \item biber - \item lualatex .tex - \item lualatex .tex -\end{enumerate} - -\newpage - -\section{Section} - -section - -\subsection{Sub Section} - -sub section - -\paragraph{Paragraph} - -paragraph diff --git a/section/program-1.tex b/section/program-1.tex new file mode 100644 index 0000000..24867d0 --- /dev/null +++ b/section/program-1.tex @@ -0,0 +1,13 @@ +\section{演習課題1} + +出力に「C言語」と表示するプログラム + +\subsection{コードリスティング} +\defaultlistingstyle +\lstinputlisting[language=C, title={演習課題1}]{../programs/prog1.c} + +\subsection{実行結果} + +\begin{center} + \includegraphics[width=\textwidth]{./assets/prog1_output.png} +\end{center} diff --git a/section/program-2.tex b/section/program-2.tex new file mode 100644 index 0000000..429cb04 --- /dev/null +++ b/section/program-2.tex @@ -0,0 +1,13 @@ +\section{演習課題2} + +出力に「C言語」を縦書きで表示するプログラム + +\subsection{コードリスティング} +\defaultlistingstyle +\lstinputlisting[language=C, title={演習課題2}]{../programs/prog2.c} + +\subsection{実行結果} + +\begin{center} + \includegraphics[width=\textwidth]{./assets/prog2_output.png} +\end{center} diff --git a/section/program-3.tex b/section/program-3.tex new file mode 100644 index 0000000..f065607 --- /dev/null +++ b/section/program-3.tex @@ -0,0 +1,14 @@ +\section{演習課題3} + +出力に「情報処理」を右に向かって斜めに表示するプログラム + +\newpage + +\subsection{コードリスティング} +\lstinputlisting[language=C, title={演習課題3}]{../programs/prog3.c} + +\subsection{実行結果} + +\begin{center} + \includegraphics[width=\textwidth]{./assets/prog3_output.png} +\end{center} diff --git a/section/program-4.tex b/section/program-4.tex new file mode 100644 index 0000000..5d29895 --- /dev/null +++ b/section/program-4.tex @@ -0,0 +1,13 @@ +\section{演習課題4} + +3つのint型整数y,m,dを宣言し,yは誕生年,mは誕生月,dは誕生日で初期化し,y+m+dの値を「○○○○の生年月日の和は****です.」と表示するプログラム + +\subsection{コードリスティング} +\vspace{-0.5cm} +\lstinputlisting[language=C, title={演習課題4}]{../programs/prog4.c} + +\subsection{実行結果} + +\begin{center} + \includegraphics[width=\textwidth]{./assets/prog4_output.png} +\end{center} diff --git a/section/syntax.tex b/section/syntax.tex new file mode 100644 index 0000000..739511d --- /dev/null +++ b/section/syntax.tex @@ -0,0 +1,56 @@ +\section{今回の構文} + +\subsection{\texttt{printf}関数} + +\texttt{printf}とはPrint Formatのことで、第一引数に書式(文字列)、第二以降の引数に表示したいデータ(変数、定数、リテラル)を羅列する。 +この関数は\texttt{stdio.h}を\lstinline[columns=fixed]{#include}(ソースコードに含める)ことで利用できる。\cite{cppref_printf} + +\defaultlistingstyle +\begin{lstlisting}[language=C,title={\texttt{printf}関数}] +printf("<書式>", <データ1>, <データ2>, ...); +\end{lstlisting} + +書式には以下のような物がある: + +\begin{lstlisting}[language=C,title={\texttt{printf}の書式(一部)\cite{xiny}}] +"%d" // 整数 +"%f" // 浮動小数点 +"%c" // 文字(単一) +"%s" // 文字列 +\end{lstlisting} + +更に、書式には文字の表示を制御できる特殊文字(escape sequence)があり、一部の文字はソースコードと干渉するためそれらを使用しないと表示できない。特殊文字はバックスラッシュで始まり、ASCII文字1つが続く。 + +\begin{lstlisting}[language=C,title={特殊文字(一部)\cite{xiny}}] +"\n" // 改行 +"\\" // バックスラッシュ +"\?" // 疑問符 +"\"" // ダブルクウォーテーションマーク +"\'" // シングルクウォーテーションマーク +\end{lstlisting} + +\newpage + +\subsection{変数宣言・定義}\label{var_decl_def} + +変数はコンピュータのメモリ上にある値が入る箱のような物である。この箱には整数や小数値、文字などが入るが、メモリ上ではすべて1と0で表現されている。 +この一次元な1と0の海の中でどうやってプログラムが値の種類を決定しているのかというと、それはコンパイラが機械語に変換する際に変数名に添えられた型から読み出す時の必要な1と0の列の長さを実行ファイルに書き込んでいるのだ。 + +C言語で変数を扱うには二つの操作が必要である。 +1つは変数の宣言、もう1つは変数の定義である。 +変数の宣言とは文字通り変数の存在を宣言することである。 +具体的にはその変数を格納する場所をメモリ上に作ることである。 +そして変数の定義は値の代入と言い替えることができ、宣言で作られた場所に値を書き込む操作である。 + +ソースコードでは次のようになる: + +\begin{lstlisting}[language=C,title={変数の例}] +int a; // 整数型の変数の宣言 +a = 17; // 変数名 a に 17 という値を書き込む +\end{lstlisting} + +上記の書き方はC99などの標準規格が制定される前のソースコードによく見られるが、C99以降からは1行で宣言と代入が出来るようになっている。\cite{cppref_decl} + +\begin{lstlisting}[language=C,title={C99以降の変数宣言・代入}] +int a = 17; // 整数型の変数 a の宣言と同時に 17 という値を書き込む +\end{lstlisting}