アセンブリで.textに文字列を定義したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
黒船
記事: 29
登録日時: 11年前
住所: 東京都目黒あたり

アセンブリで.textに文字列を定義したい

#1

投稿記事 by 黒船 » 11年前

nasmを学習しています。
環境はlinux(mint)です。
以下のプログラムのように
message db 'hello, world', 0x0a
を.textで定義するとアセンブルできるのですが、
実行すると
Segmentation fault
と表示されてしまいます。
なぜなのですか?
あと .textでも定義できるようになるにはどうしたらいいのですか。
よろしくおねがいします。

コード:

section .data	 ; データセクションの定義  
section .text
global _start	                ; エントリーポイント

jmp  _main                      ; ジャンプ

_start:
message	db 'hello, world', 0x0a
mov	edx, 13		; スタックにバッファを設定
mov	eax, 4			; 出力(sys_write)
mov	ebx, 1			; ファイルハンドル(1=標準出力 > ディスプレィに表示)
_main:	
mov	ecx, message		; 文字列
int	0x80			; システムコール,出力する

mov	eax, 1                 ; sys.exit
mov	ebx, 0                 ; 終了ステータスコード 
int	0x80                   ; システムコール,終了する


アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: アセンブリで.textに文字列を定義したい

#2

投稿記事 by softya(ソフト屋) » 11年前

jmp _main ; ジャンプ
が意味不明なのですが、どんな意図が?

【追記】
_start:
message db 'hello, world', 0x0a
で今回の問題ですが、コレがマズイと思います。

それに関連して上に書いたjmpを入れる場所が問題です。
あるいはmessage を置く場所を変えるかです。

アセンブラでは命令コードとデータは自分でちゃんと分けてやらないといけませんが、それが出来ていないのが問題なのと、エントリーポイントの意味をちゃんと理解していないのも問題かと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
黒船
記事: 29
登録日時: 11年前
住所: 東京都目黒あたり

Re: アセンブリで.textに文字列を定義したい

#3

投稿記事 by 黒船 » 11年前

これといった意図はないです。
このコードは
サイトにあるものを自分が少し変更を加えただけのものですから、
変な箇所が出てしまいました。
以後気をつけます。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: アセンブリで.textに文字列を定義したい

#4

投稿記事 by softya(ソフト屋) » 11年前

黒船 さんが書きました:これといった意図はないです。
このコードは
サイトにあるものを自分が少し変更を加えただけのものですから、
変な箇所が出てしまいました。
以後気をつけます。
追記で書きましたが、問題点は理解出来ましたでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
黒船
記事: 29
登録日時: 11年前
住所: 東京都目黒あたり

Re: アセンブリで.textに文字列を定義したい

#5

投稿記事 by 黒船 » 11年前

すこし 話が変わるのですが、
今 サーバから送られてきたデータをメモリ上に展開し、
実行するというプログラムを作っています。
うまく説明できませんが
実行ファイルがなくても実行できるプログラム(クラウド アプリケーション?)
を作りたいと思っています。
しかし、そのためには純粋なアセンブリで開発しなければいけなくて、
(余計なヘッダや、.idataがあるとうまく実行できないので ・・・この認識が間違っていたらご指摘おねがいします。)
どうしても.textに文字列を埋め込みたいです。

softyaさんの
>アセンブラでは命令コードとデータは自分でちゃんと分けてやらないといけません

は理解していますが、先にあげたような理由があったので
ひょっとしたら何か良い方法が他にあるのではと思って質問しました。
なのでそこのところはある程度わかっています。

ただ、エントリーポイントの箇所はいまいちわかっていません。

jmp _mainと_mainを消してエントリーポイントの問題は解決したと思っています。

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: アセンブリで.textに文字列を定義したい

#6

投稿記事 by YuO » 11年前

黒船 さんが書きました:今 サーバから送られてきたデータをメモリ上に展開し、
実行するというプログラムを作っています。
うまく説明できませんが
実行ファイルがなくても実行できるプログラム(クラウド アプリケーション?)
を作りたいと思っています。
それはクラウドアプリケーションではないですし,データ領域上のプログラムコードを実行することは,通常許されません。
データ領域のページのNXビットは少なくとも最近の64bit OSでは通常デフォルトで有効だと思いますが……。

ダウンロードしてテンポラリに書き出して実行する,インタプリタとして実行する,などのことをする必要があります。
ダウンロードしてテンポラリに書き出したなら,セキュリティを考えて本来ならサンドボックス作らないといけませんけどね。
まぁ,JavaなどでJITがないと使い物にならないので,何らかの対応方法があるとは思いますが……。
# WindowsではVirtualAllocExのflProtectにPAGE_EXECUTE系の値を渡す,という形です。Linux系は探したがわからなかった……。
オフトピック
クラウドアプリケーションというと,クラウド環境下で実行されるアプリケーションが想像されます。
原則的にクラウドサーバー側にアプリケーションがあり,クライアント側は主にブラウザか,専用アプリケーションでもViewと自身のマネージメントを行う程度の機能しかないイメージです。
e.g.) Google Apps, Office Web Apps等。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: アセンブリで.textに文字列を定義したい

#7

投稿記事 by softya(ソフト屋) » 11年前

黒船 さんが書きました:すこし 話が変わるのですが、
今 サーバから送られてきたデータをメモリ上に展開し、
実行するというプログラムを作っています。
うまく説明できませんが
実行ファイルがなくても実行できるプログラム(クラウド アプリケーション?)
を作りたいと思っています。
しかし、そのためには純粋なアセンブリで開発しなければいけなくて、
(余計なヘッダや、.idataがあるとうまく実行できないので ・・・この認識が間違っていたらご指摘おねがいします。)
どうしても.textに文字列を埋め込みたいです。
既に書かれている通り、データ領域にあるコードを実行するために色々工夫が必要です。
うっかりするとウィルス対策ソフトにウイルス扱いされるかも。
Linuxの実行権は詳しくないのでコメントできません。
黒船 さんが書きました: softyaさんの
>アセンブラでは命令コードとデータは自分でちゃんと分けてやらないといけません

は理解していますが、先にあげたような理由があったので
ひょっとしたら何か良い方法が他にあるのではと思って質問しました。
なのでそこのところはある程度わかっています。

ただ、エントリーポイントの箇所はいまいちわかっていません。

jmp _mainと_mainを消してエントリーポイントの問題は解決したと思っています。
エントリーポイントは、実行ファイルとして扱った時に一番最初にプログラムカウンタが設定されるアドレスです。
特殊な使い方をされるようなので、エントリーポイント自体が無意味だと思います。

それとデータは命令の後に書けば命令コードとして実行されないので、そこに書いてください。
ただし、リロケーターブルなアドレッシングの命令だけで書かれていないと実行するのは困難です。

あと
mov ecx, message ; 文字列
がリロケータブルな命令に展開されるのかnasmの機能を確認してください。コンパイルオプションでも変わるかもしれません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
黒船
記事: 29
登録日時: 11年前
住所: 東京都目黒あたり

Re: アセンブリで.textに文字列を定義したい

#8

投稿記事 by 黒船 » 11年前

ずいぶん返信が遅くなってしまいました。
皆様のアドバイスを元に勉強しなおし、
アセンブルし、デバッグすることによって
mov ecx, message ; 文字列
はリロケータブルではないことがわかりました。
なので、callを使って実現することになりました。
以下のような感じで実現しました。
動作確認済みです。
この質問はここで解決にさせて頂きます。
ありがとうございました。

コード:

section .text
global _start                   ; エントリーポイント
_start:
	starter:
	call data
	mov eax, 4          ; 出力(sys_write)
	mov ebx, 1          ; ファイルハンドル(1=標準出力 > ディスプレィに表示)
	pop ecx
	mov edx, 16     ; スタックにバッファを設定
	int 0x80            ; システムコール,出力する
	jmp short	dummy
	nop
	
	data:
	call	[esp]
	db 'AAAAAAAAAAAAAAA', 0x0a
	
	ender:
	mov eax, 1                 ; sys.exit
	mov ebx, 0                 ; 終了ステータスコード 
	int 0x80                   ; システムコール,終了する


閉鎖

“C言語何でも質問掲示板” へ戻る