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

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

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

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

C

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

Q&A

解決済

2回答

2047閲覧

アセンブリのコンパイルができません。

strike1217

総合スコア651

アセンブリ言語

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

C

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

0グッド

0クリップ

投稿2017/07/04 05:32

編集2017/07/04 06:10

printf()のシステムコールを自作しました。
アセンブリ言語を勉強し始めたばかりです。
64 bit linux, Debian系です。intel CPU

システムコール番号の確認
linux-4.7.3/arch/x86/entry/syscalls/syscall_64.tbl

0 common read sys_read 1 common write sys_write 2 common open sys_open 3 common close sys_close 4 common stat sys_newstat

writeシステムコールを使用するので、1番ですね!!

// write.S .global _write _write: push %rbx mov $1, %rax mov 8(%rsp), %rbx mov 12(%rsp), %rcx mov 16(%rsp), %rdx syscall pop %rbx ret

C

1int main(){ 2 _write(1, "Hello_World\n!!", 14); 3 return 0; 4}

一番最初のパラメータはファイルディスクリプタを1にしています。

bash

1gcc -c write.S -o write.o 2gcc -c main.c -o main.o 3 4gcc main.o -lc write.o // リンク 5 6gcc main.c write.S -o _write //こちらでやると warningが出てきますね。

warning、エラーともにありません。
が・・・・

実行しても何も表示されません。
なぜでしょうか?
教えてください。

「追記」
少し修正しました。

starceでおかしい部分を探しました。

printf()の正常な場合は・・・
write(1, "Hello_World!!\n", 14Hello_World!!
) = 14

上記のアセンブリの場合・・・
write(1, "Hello_World!!\n\0\0\1\33\3;<\0\0\0\6\0\0\0\320\375\377\377"..., 94771697825424) = -1 EFAULT (Bad address)
exit_group(0) = ?

なんか途中からおかしな文字列が入り込んでいますね・・・
なんでしょうかね??これ・・・・

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

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

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

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

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

t_obara

2017/07/04 07:07

mattさんが指摘されている長さが怪しいと思いますが、Cで例示されている文字列とエラーで表示している内容で、!!¥nの位置関係が違います。再確認してください。
guest

回答2

0

ベストアンサー

既に同じ引数構成でスタックに乗っているので

asm

1// write.S 2.global _write 3 4_write: 5 push %rbx; 6 mov $1, %rax; 7 syscall 8 pop %rbx 9 ret

で呼べると思います。おそらくですが

asm

1// write.S 2.global _write 3 4_write: 5 push %rbx 6 mov $1, %rax 7 mov 8(%rsp), %rbx 8 mov 12(%rsp), %rcx 9 mov 16(%rsp), %rdx 10 syscall 11 pop %rbx 12 ret

length のスタックがおかしいかと。

投稿2017/07/04 07:02

mattn

総合スコア5030

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

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

strike1217

2017/07/04 07:20 編集

mov 16(%rsp), %rdx こいつですよね?? mov $0xe, %rdxにてみたら、文字列は表示されました。 16ではおかしいんですかね?
strike1217

2017/07/04 07:18

mov 16(%rsp), %rdx どのように変更すればよいのでしょうか?
mattn

2017/07/04 07:20

やろうとされている事が良く分からないです。積まれたスタックを再登録されているのでしょうか?
strike1217

2017/07/04 07:23

本を参考にしてやっているので・・・ アセンブリ初心者です。 この場合、write()が呼ばれる時に、1やHello_World!!\n, 14というパラメータはすでにレジスタに入れらるんでしょうか?
strike1217

2017/07/04 07:35

回答の上のプログラムでできました!! writeシステムコールを呼び出す時はシステムコール番号のみ指定すれば、できるんですね!! わかりました。
mattn

2017/07/04 07:38

はい。引数同じなので sys_write 呼び出せるはずです。
strike1217

2017/07/04 07:46

では、自分がやっていることは、「スタック内に積んであるパラメータを再度レジスタに代入している」 ということですかね?
mattn

2017/07/04 07:48

そうなります
strike1217

2017/07/04 07:50

はは~~~ん。 なるほど! 文字列の長さもスタックのどこかにあるわけですよね? そのスタックを指し示している場所がおかしいということですね!! mov 16(%rsp), %rdx
carnage0216

2018/02/24 11:08

失礼します。 strike1217さんに質問したいのですが、何の本を参考にされたのですか?またその本にはprintf関数自体をアセンブリ言語で書いたりしているのでしょうか? どうかよろしくお願いいたします。
strike1217

2018/02/24 11:20 編集

> carnage0216さん んーー。 本ですか・・・ アセンブリ関連の本なら持っています
strike1217

2018/02/24 11:21

失礼しました。 んーーーと・・・ちょっとまってください。
carnage0216

2018/02/24 11:57

わざわざどうもありがとうございます。 早速調べさせていただきます。 どうもありがとうございました。
guest

0

  1. syscallのパラメータは、rdi, rsi, rdx, ...ではないか?
  2. スタックの幅が32bitだけど大丈夫か?

以上、2点が気になりました。

1番については下記の記事を参考にしました。

2番については何となく思っただけですが、デバッガで確認できると思いますので確認して下さい。

投稿2017/07/04 06:44

fuzzball

総合スコア16731

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

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

strike1217

2017/07/04 06:51

mov $1, %rax mov 8(%rsp), %rdi mov 12(%rsp), %rsi mov 16(%rsp), %rdx さらにおかしな事になりました。 write(161945215, 0x9a716900000560b, 94605406574224) = -1 EBADF (Bad file descriptor) segmentation faultです。
fuzzball

2017/07/04 07:03 編集

_writeに入った時点のスタックを確認して下さい。同じ環境を用意できないので、結果だけ提示されても分かりません。
strike1217

2017/07/04 07:07

おかしな部分が見つかりました。 mov 16(%rsp), %rdx これが変なようです。 どう変更したらいいのかが分からないのですが・・・・
fuzzball

2017/07/04 07:09

なぜおかしいと思ったのでしょうか?
strike1217

2017/07/04 07:16

この部分を以下のように変更しました。 mov 0xe, %rdx 出来ました。ただパラメータ渡しではなく、ベタ貼りです。
fuzzball

2017/07/04 07:18

$0xe ではなく 0xe ですか?
strike1217

2017/07/04 07:20 編集

あ、そうです。 すいません。間違えました。 $0xeのほうです。
fuzzball

2017/07/04 07:25

で、writeが呼ばれたときのスタックを書く気はないのでしょうか?
strike1217

2017/07/04 07:30

いえ、本当はスタックに書いて、それをレジスタに転送して、syscallを呼び出したいんですが、 mov 16(%rsp), %rdx をどのように変更すればよいのかが分かりません。
fuzzball

2017/07/04 07:40 編集

いや、実行してwriteが呼ばれた時点でスタックがどうなっているのか書いて下さい、と言っているのですが。
strike1217

2017/07/04 07:41

あ、そういう意味でしたか! すいません。 少々お待ちを
fuzzball

2017/07/04 07:43

解決してるなら、もういいですよ。
strike1217

2017/07/04 07:48

こうなりました。x/50wx $rsp 0x7fffffffd5a8: 0x555546af 0x00005555 0x555546c0 0x00005555 0x7fffffffd5b8: 0xf7a5a2b1 0x00007fff 0x00040000 0x00000000 0x7fffffffd5c8: 0xffffd698 0x00007fff 0xf7b9b288 0x00000001 0x7fffffffd5d8: 0x55554690 0x00005555 0x00000000 0x00000000 0x7fffffffd5e8: 0x709c1acf 0x7c3541ba 0x55554560 0x00005555 0x7fffffffd5f8: 0xffffd690 0x00007fff 0x00000000 0x00000000 0x7fffffffd608: 0x00000000 0x00000000 0x569c1acf 0x296014ef 0x7fffffffd618: 0xb9ce1acf 0x2960045b 0x00000000 0x00000000 0x7fffffffd628: 0x00000000 0x00000000 0x00000000 0x00000000
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問