質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

コンパイラ

コンパイラは、プログラミング言語で記述したソースコードを、コンピュータの実行形式であるオブジェクトコードに変換するプログラムです。

Q&A

解決済

3回答

1360閲覧

rspでのスタックの領域確保についての疑問

退会済みユーザー

退会済みユーザー

総合スコア0

アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

コンパイラ

コンパイラは、プログラミング言語で記述したソースコードを、コンピュータの実行形式であるオブジェクトコードに変換するプログラムです。

0グッド

0クリップ

投稿2020/09/06 11:29

過去の質問とは別に重ねて質問させて頂きます。
ちょっとわからないことが多すぎるので3つに分けて質問させて頂きます。
下記のC言語を逆アセンブルしてアセンブラを見てみました。

c言語

int main(){ printf("helloWorld\n"); printf("Tata");

逆アセンブル結果

sub rsp, 28h lea rcx, aHelloworld ; "helloWorld\n" call sub_140001090 lea rcx, aTata ; "tata" call sub_140001090 xor eax, eax add rsp, 28h retn endp

サブルーチン sub_140001090

.text:0000000140001040 sub_140001040 proc near ; CODE XREF: sub_140001090+3C↓p .text:0000000140001040 ; DATA XREF: .pdata:000000014001E00C↓o .text:0000000140001040 .text:0000000140001040 var_18 = qword ptr -18h .text:0000000140001040 arg_0 = qword ptr 8 .text:0000000140001040 arg_8 = qword ptr 10h .text:0000000140001040 arg_10 = qword ptr 18h .text:0000000140001040 arg_18 = qword ptr 20h .text:0000000140001040 .text:0000000140001040 mov [rsp+arg_18], r9 .text:0000000140001045 mov [rsp+arg_10], r8 .text:000000014000104A mov [rsp+arg_8], rdx .text:000000014000104F mov [rsp+arg_0], rcx .text:0000000140001054 sub rsp, 38h .text:0000000140001058 call sub_140001030 .text:000000014000105D mov rcx, [rsp+38h+arg_18] .text:0000000140001062 mov [rsp+38h+var_18], rcx .text:0000000140001067 mov r9, [rsp+38h+arg_10] .text:000000014000106C mov r8, [rsp+38h+arg_8] .text:0000000140001071 mov rdx, [rsp+38h+arg_0] .text:0000000140001076 mov rcx, [rax] .text:0000000140001079 call sub_140004188 .text:000000014000107E add rsp, 38h .text:0000000140001082 retn .text:0000000140001082 sub_140001040 endp

①何のために最初にsub命令で、最終的にaddをしているか。
調べたところによると変数などの領域を確保するとありますが、どうして領域が確保されるかわかりません。
最終的addをするのであれば領域は変わらないのでは。
rspの領域を確保するというイメージができていませんので
イメージ説明

②サブルーチン(sub_140001090)で一度arg_0という変数に8バイトアラインされた値を格納し、順番にアドレスにして言ってますが、イメージ的には下の図のような感じでよろしいでしょうか?
イメージ説明
1マスが8バイトで下に行けば行くほどアドレス値は大きくなります。

③サブルーチン(sub_140001090)内でr8,r9,rdx,rcxが使われているのは何故でしょう。
これもコンパイラがそう決めているからということなのでしょうか?

独学でやっているので初心者すぎる質問かもしれないですがご回答をどうかよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

rsp から引き算し、新しく増えた領域のみを現在実行中の関数のローカル変数として使うという約束によって成り立っています。 rsp に足し算すれば領域の解放です。 もちろんあなたがそうしたければ他の形でメモリを使うこともできなくはないのですよ。

それとスタックは引数の受け渡しにも使われる場合があり、具体的なルールは呼出規約に定めがあります。 基本的にはコンピュータのアーキテクチャを決定しているところが策定することが多いのですが、同じアーキテクチャのコンピュータでも OS によって若干の違いがある場合もあります。

r8 r9 rdx rcx が使われているのもこの呼出規約の定めによるものです。 マイクロソフトのサイトに説明のページを見つけたので参考にしてください。 (繰り返しますが他の OS では細部が違う可能性はあります。 正確なところは各環境におけるドキュメントを探してみてください。)

https://docs.microsoft.com/ja-jp/cpp/build/x64-calling-convention?view=vs-2019

質問者の事例で言えば、引数として受け取った値を改めて別の関数に渡すために別の入れ物に移し替え (mov) ているということです。

投稿2020/09/06 12:29

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

領域を確保する、というよりも、他に使われることはないメモリ領域を空ける、と考えましょう。
基本的に、スタックポインタより上の(アドレスの)メモリは、その関数が終わるまで使われることはありません

#関数コールやレジスタ退避では常にスタックの低い方に伸びていきます

んで、その開けた領域に、引数やローカル変数を割り当てていきます

投稿2020/09/06 12:25

編集2020/09/06 12:30
y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/06 13:13 編集

いつもご説明ありがとうございます。 >関数コールやレジスタ退避では常にスタックの低い方に伸びていきます。 ちょっと勘違いがあってはいけないので 簡単に図解すると アドレス値低い ↑         __________________ ↑        | 関数コール、レジスタ | ↑        |            | スタックポインタ→|-------------------------- ↓        |  空けたメモリー領域 | ↓        |  引数、ローカル変数 | アドレス値高い   ___________________ 雑ですいませんが、上のような図であっていますか?
y_waiwai

2020/09/06 13:27

そうですね。それであってます
退会済みユーザー

退会済みユーザー

2020/09/06 13:56

ありがとうございます。
guest

0

①何のために最初にsub命令で、最終的にaddをしているか。

sub 28hすると28hバイト分のメモリがスタック上に確保されることになります。
add 28hすることでその領域を開放します。

投稿2020/09/06 12:10

otn

総合スコア84555

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問