今日、私は関数に別のエントリ・ポイントを作成するために、アセンブリコードで関数ポインタをインクリメントして遊ん:(私が知っている、それはCRTが初期化されずにputs
を呼び出しますので、技術的には、このコードは無効ですこのアセンブリコードに類似したC言語での操作はありますか?
.386
.MODEL FLAT, C
.DATA
INCLUDELIB MSVCRT
EXTRN puts:PROC
HLO DB "Hello!", 0
WLD DB "World!", 0
.CODE
dentry PROC
push offset HLO
call puts
add esp, 4
push offset WLD
call puts
add esp, 4
ret
dentry ENDP
main PROC
lea edx, offset dentry
call edx
lea edx, offset dentry
add edx, 13
call edx
ret
main ENDP
END
が、これは少なくともアセンブリやランタイムエラーがなくても動作します)。
dentry
への2回目の呼び出しでは、以前のようにedx
レジスタの関数のアドレスを取得しましたが、今回はインクリメントしましたその関数を呼び出す前に13バイト分。
このプログラムの出力は、したがってある:
C:\Temp>dblentry
Hello!
World!
World!
C:\Temp>
第二出力が始まるコールからのものであるのに対し、「Hello!\nWorld!
」の最初の出力は、関数の先頭への呼び出しです " push offset WLD
"命令である。
C、Pascal、FORTRANなどのアセンブラからステップアップすることを意図した言語でこの種のものが存在するのだろうかと思います。私はCが関数ポインタを増やすことはできませんが、このようなことを達成するための他の方法があるのは分かりますか?
参照してください。より高水準の言語(さらにはその点ではasm)では、2つの別々の関数に分割し、一方を他方の関数と呼び、コンパイラに最適な実装を選択させる必要があります。 – Jester
私は以前のFORTRANが関数の複数のエントリーポイントをサポートしていると信じていました。すばやいgoogle検索ではhttps://gcc.gnu.org/onlinedocs/gcc-3.4.4/g77/Alternate-Entry-Points.htmlとhttps:/ /docs.oracle.com/cd/E19957-01/805-4939/6j4m0vn99/index.html – ninjalj
実際の質問は、どうしてこのようにしたいのですか?これはメンテナンスの悪夢です。最適化まで:プログラムの99%以上がこれを必要としません。残りの部分は、コンパイラや70/80ies BASICのハッキングよりはるかに良い構造で最適化することができます。 – Olaf