【アセンブラ】レジスタで指定したアドレスをサブルーチンとして呼び出したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

【アセンブラ】レジスタで指定したアドレスをサブルーチンとして呼び出したい

#1

投稿記事 by みけCAT » 12年前

Windows Vista Home Premium SP2 32ビット
gcc 4.7.2
自作開発補助ツール(添付)
VirtualBox 4.2.18
Virtual Floppy Drive for Windows 2.1.2008.0206

アセンブラで、OSに依存しないプログラムの作成に挑戦しています。
レジスタもしくはメモリに格納したアドレスをサブルーチンとして呼び出したいのですが、うまくいかなくて困っています。

コード:

.code16gcc

.org 0x0500

.global _start
_start:
	mov %bx,outputnumber
	mov %cx,searchfile
	mov %dx,getfiledata
	jmp _main

outputnumber:
	.word 0x0500
searchfile:
	.word 0x0500
getfiledata:
	.word 0x0500

callapi:
	mov $0x0E31,%ax
	mov $0x0007,%bx
	int $0x10
#	pushw $CALLAPIRETURN
#	push %si
#	ret
	call *%si
CALLAPIRETURN:
	mov $0x0E32,%ax
	mov $0x0007,%bx
	int $0x10
	ret

filename:
	.ascii "DATA    DAT"
filesizestr:
	.ascii "File size   : ";
filecrcstr:
	.ascii "CRC16 value : ";
filenotfoundstr:
	.ascii "file \"DATA.DAT\" not found.\r\n"

_main:
	mov $0x0E30,%ax
	mov $0x0007,%bx
	int $0x10
	mov $7777,%cx
	mov outputnumber,%si
	call callapi
	mov $0x0E33,%ax
	mov $0x0007,%bx
	int $0x10
	hlt

	lea filename,%dx
	mov searchfile,%si
	call callapi
	test %ax,%ax
	jz not_found
	push %ax
	push %bx
	mov $0x0300,%ax
	xor %bx,%bx
	int $0x10
	mov $0x1301,%ax
	mov $0x0007,%bx
	mov $14,%cx
	lea filesizestr,%bp
	int $0x10
	pop %cx
	push %cx
	mov outputnumber,%si
	call callapi
	mov $0x0E0D,%ax
	mov $0x0007,%bx
	int $0x10
	mov $0x0A,%al
	int $0x10
	pop %bx
	pop %ax
	hlt

not_found:
	mov $0x0300,%ax
	xor %bx,%bx
	int $0x10
	mov $0x1301,%ax
	mov $0x0007,%bx
	mov $28,%cx
	lea filenotfoundstr,%bp
	int $0x10
	hlt

#put number to output on %cx then call this
outputnumber2:
	push %ax
	push %cx
	push %dx
	push %bx
	pushw $10
MAKEOUTPUTLOOP:
	mov %cx,%ax
	xor %dx,%dx
	mov $10,%bx
	div %bx
	push %dx
	mov %ax,%cx
	test %cx,%cx
	jnz MAKEOUTPUTLOOP
	mov $0x0E,%ah
	mov $0x0007,%bx
OUTPUTLOOP:
	pop %cx
	cmp $10,%cx
	je OWARIDAYO
	mov %cl,%al
	add $48,%al
	int $0x10
	jmp OUTPUTLOOP
OWARIDAYO:
	pop %bx
	pop %dx
	pop %cx
	pop %ax
	ret
まず、添付したFDDディスクイメージをVirtual Floppy Driveでマウントします。
このコードを自作開発補助ツールのasbl.plでバイナリに変換し、マウントしたディスクのルートにBOOT.BINという名前で保存します。
(添付したディスクイメージには既にBOOT.BINが書き込まれており、このまま起動できます)
VirtualBoxでフロッピーディスクとしてマウントしたディスクを「ホスト ドライブ」で使用するように設定し、そのディスクから起動します。

「01777723」と表示されて欲しいのですが、「0177771」と表示されてしまいます。
このコードは、%bxに下のoutputnumber2と同じコードの先頭アドレスが格納された状態で呼び出されます。
pushw~retの3行のコメントアウトを解除し、その下のcall *%siをコメントアウトしたところ、何も表示されませんでした。

どうすれば、うまくレジスタで指定したアドレスをサブルーチンとして呼び出せるのでしょうか?
レジスタではなく、メモリに格納してあるアドレスでもかまいません。

よろしくお願いします。

この辺のサイトを参考に制作しています。
http://www5c.biglobe.ne.jp/~ecb/assembl ... ler00.html
http://community.osdev.info/index.php?%28AT%29BIOS
http://softwaretechnique.web.fc2.com/OS ... index.html
http://d.hatena.ne.jp/rascal_k2/20091113/1258116593
添付ファイル
regctest.zip
ディスクイメージ・プログラムのソースコード
(6.73 KiB) ダウンロード数: 110 回
tools.zip
自作開発補助ツール
(5.23 KiB) ダウンロード数: 107 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: 【アセンブラ】レジスタで指定したアドレスをサブルーチンとして呼び出したい

#2

投稿記事 by ISLe » 12年前

動作確認はしてませんが。
code16gccだとret→retlに変換されるので、pushw $CALLAPIRETURNに対して余分にスタックから吸い上げてしまうような気がします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 【アセンブラ】レジスタで指定したアドレスをサブルーチンとして呼び出したい

#3

投稿記事 by みけCAT » 12年前

ありがとうございます。
loader.s(添付)とcrc16.s(今回貼り付けたソースコード)の.code16gccと.orgの間に以下のコードを追加したところ、
期待した動作になりました。

コード:

.macro call operand
	callw \operand
.endm

.macro ret
	retw
.endm
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 【アセンブラ】レジスタで指定したアドレスをサブルーチンとして呼び出したい

#4

投稿記事 by みけCAT » 12年前

タイトルは「レジスタで指定したアドレスを~」としましたが、
本来の目的はメモリに格納してあるアドレスをサブルーチンとして呼び出すことだったので、
例えばoutputnumberに格納したアドレスを呼び出したいなら

コード:

call *outputnumber
の一行で呼び出すことができ、callapiのルーチンは必要ないことがわかりました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

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