はじめまして.たんぐすてんです.
C言語で最近知ったことがあったので書きます.が,あまり高度なことは書けないのでハードルは低めでお願いします.
トリビア的なものなので知識として役立たない可能性が高いです.
皆さんよくご存知のCコードです.
#include <stdio.h>
int func(){
return 0;
}
int main(void){
int a;
a = func();
printf("a = %d\n", a);
return 0;
}
func関数は引数が宣言されていませんがここに引数を渡すことは別に怒られないことを知りました.
#include <stdio.h>
int func(){
return 0;
}
int main(void){
int a;
a = func(100);/*エラーにはならない*/
printf("a = %d\n", a);
return 0;
}
C++では怒られていたので気づきませんでした(という言い訳をしつつ).
どうやら引数に名前はないが,値はレジスタには乗っかってるらしい(x86ではスタックかな).
これを使えば仮引数を宣言していないのに実引数の値受け取って演算する不思議関数がつくれるのではと考えました.
ということで,「レジスタを直接いじったら行けるんじゃね?」ってことで実際にやってみた.
超簡単な加算コードを書いて実験.アセンブリはAT&T記法ではなくインテル記法です.
#include <stdio.h>
int add();/*code.asmに定義*/
int main(void){
int a;
a = add(100, 200);/*引数を渡す*/
printf("a = %d\n", a);
return 0;
}
;add関数の中身
;足し算して返すだけ
_TEXT segment
public add
align 16
func proc
mov rax, rcx
add rax, rdx
ret
func endp
_TEXT ends
end
実行結果 : a = 300
加算できた.
引数が宣言されていないのに引数を2つ受け取って加算結果を返す関数が出来上がりました.
もうちょっと複雑なこともやってみようかとも思いましたがこれ以上発展性もないし力尽きたのでやめました.
それでは.
実行環境:
Visual Studio 2015 (ちょうど手元にこれしかありませんでしたごめんなさい)