マクロアセンブラの仕様について

このQ&Aのポイント
  • マクロアセンブラの仕様とは?
  • C言語でfmodを呼び出すコードの展開
  • fmodの引数の渡し方について資料を探しています
回答を見る
  • ベストアンサー

マクロアセンブラの仕様について

以下のコードは、C言語でfmodを呼び出したものです。 include <sunmath.h> #include <math.h> #include <stdio.h> #include <stdlib.h> int main (int argc,char **argv) { double wk_mod; double wk_data = 40000000000.0; wk_mod = fmod(wk_data,(double)10); return 0; } -------------------------------- これをアセンブラに展開するとfmodの行は以下のようになりました。 / Line 9 movsd .L_cseg1, %xmm1 movsd -40(%rbp), %xmm0 movl $2, %eax call fmod movsd %xmm0, -48(%rbp) movsd -48(%rbp), %xmm0 movl $0, %eax movsd %xmm0, -32(%rbp) ----------------------------- ここで、fmodの第1引数は%xmm0、第2引数は%xmm1経由で、渡されると推測していますが、この裏付けをとりたいために、callを行ったときの パラメータの渡し方が記述されている資料を探しています。 もしご存じの方がおりましたら教えて下さい。 OS sloaris10(x86) sun-studio11のCコンパイラで64ビットモードで-Sオプションでコンパイルを行いました。

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

AMD64 ABI によると, float や double の引数は (基本的に) %xmm0, %xmm1, ... の順に渡されるみたいですね.

参考URL:
http://www.x86-64.org/documentation/abi.pdf
tatsu99
質問者

お礼

ありがとうございます。早速確認してみます。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

そうそう, この辺の「レジスタの使い方や関数の呼び出しに関する規約」を ABI (Application Binary Interface) と呼びます. #1 で挙げた文献は, 「x86 solaris ABI」などのキーワードを使って Google で検索するうちにでてきたものです.

tatsu99
質問者

お礼

なるほどABIですか。#1で教えていただきましたURLの資料で、ほぼ裏付けがとれました。ありがとうございました。私もABIをキーにして検索してみます。

関連するQ&A

  • GASアセンブラのテストプログラムの作り方について

    現在、アセンブラのテストプログラムの作り方に困っています。 入力された値を関数palindへ渡し、結果を出力する様にしたいのですが、考え方がよく解りません。 関数を呼び出すには、       movl 引数, %eax       pushl %eax       call 渡す関数の名前       popl %eax とすると思うのですが、これだけでは結果を戻しただけだになると思います。 この後結果を出力するにはどのようにしたら良いでしょうか? 宜しくお願いしますm(_ _)m ・回文を作るアセンブラの関数(palind.s) 例えば8と入力した場合に2進数(1000)の回文(上から読んでも下から読んでも同じもの)、10000001と00011000を作ります。(abcd)→(abcddcba),(dcbaabcd) 答えは2個あるので、入力とは別の変数を持ってきて、その変数の値によってどちらかを返すようにします。 (2個の答えを出すには変数を変えて呼び出せば問題ないと思います)

  • c++ TCHARで文字化け

    TCHARはUNICODEが扱えるときいたので早速つかってみた。以下は引数を表示するプログラムである。 Visual C++ Express Editionを使った。 #include <stdio.h> #include <tchar.h> int _tmain(int argc, _TCHAR* argv[]) { int i=0; while(i<argc){ _tprintf(_T("%s\r\n"),argv[i++]); } return 0; } しかし上記プログラムに日本語の引数をわたすと文字化けするではないか。なでしょうか?

  • コマンドプロンプトを使用してのコマンドライン引数

    winXPのコマンドプロンプトを利用して 参考書「独習C」を使い、C言語の学習をしています。 その本の7.4の項目~main()の引数~で main(int argc,char *avgv[])を利用すると コマンドラインから引数をとることができるとありますが 私の学習環境ではうまくいきません。 具体的には #include <stdio.h> int main(int argc, char *argv[]) { int i; for(i=1; i<argc; i++) printf("%s ", argv[i]); return 0; } というプログラムを実行しても何も表示されません。 どうすればコマンドライン引数を利用できますか?

  • フルポインタ仕様にしたい。

    プロローグ ポインタはデータがメモリさせれいるアドレスを扱うので、引数では関数を呼び出すたびにデータ本体をコピーせずにすみます。 だから、限られた資源の中比較的高速のプログラムができる… でも、ポインタはスペースシャトルの機内からロボットアームで小さな作業を行う感覚で、結構厄介な存在でもあります。 でも、ポインタを気持ちよく操れないとゲームなど高速なプログラムはできません。 そこで、データのやり取りはアドレスのみというルールで、簡単なプログラム書いてみましたが、コンパイルしてくれるものの、エラーが発生して動いてくれません。どこがおかしいのでしょうかご教授おねがいします。もし、「ポインタのみで作るのは無理があるでしょう?」と思う場合は「そりゃむでっせ」とか書いてください。 #include <iostream> using namespace std; class Bass{ private: int* m_piData; // ポインタ変数(int) double* m_pdData; // ポインタ変数(double) public: void SetData(int* piData, double* pdData); void DataShow(int* piData, double* pdData); int iGatData(){return *m_piData;} double dGatData(){return *m_pdData;} }; void Bass::SetData(int* piData, double* pdData) { *m_piData = *piData; *m_pdData = *pdData; } void Bass::DataShow(int* piData, double* pdData) { cout << *piData << 'と' << *pdData << '\n'; } int main() { int iTestData=1234; // int型データ(表示用) double dTestData=20.5; // double型データ(表示用) int* piTestData; double* pdTestData; Bass* c_pBass; // private変数データ書込み・ポインタ c_pBass->SetData(&iTestData, &dTestData); // インライン関数(private変数関数)・ポインタ *piTestData = c_pBass->iGatData(); // int型 *pdTestData = c_pBass->dGatData(); // double型 // private変数参照 c_pBass->DataShow(piTestData, pdTestData); return 0; }

  • C言語プログラム能力検定の問題でわからないところがあります

    今度C言語プログラム能力検定を受けるのですが、過去問の回答ではわからず質問させてもらってます(以下ソース) ------------------------------------------ #include<stdio.h> int mod(int a, int b); int d, f = 10; main() { int a,b,c; enum cl {g,h} a=12; b=5; c=mod(a,b); a++; ++b; c=mod(a,b); printf("c=%d\n",c); ←(1) } int mod(int b, int a) { int c; c=b/a; c=b-c*a; return(c); } -------------------------------------------------- 問題は(1)はどのように出力されるでしょう?といったもので、 答え(出力結果)は「1」でした。回答の説明によると 「変数cはmain関数内で宣言され、mod関数の戻り値が格納される。 mod関数の戻り値は二つの引数の剰余であり、ここでは2回目のmod関数 の戻り値が表示される。2回目の仮引数は、aが6で、bが13で戻り値は1になる」 ということでしたが>mod関数の戻り値は二つの引数の剰余であり… というのがよくわかりません…剰余算というのは「%」のことですよね? であれば「c= a % b」といった記述がでてくれば13÷6=2…1で「1」となり、理解できるのですが、それらしき記述がないので(--;) どなたか教えていただけないでしょうか? よろしくおねがいします。

  • _TCHAR*での引数の読み込み

    VC++2010での、通常の #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { return 0; } のウィザードを使って、arvg[1]やargv[2]に引数を与えて、本体内で通常のCで使う printf("%s\n", argv[1]); や fopen(argv[1], "r"); を使いたいのですが、引数の型が_TCHAR*になっているため文字がそのまま使えません。 int main(int argc, char *argv[]) で使えば問題なく使えるのですが、デフォルトのウィザードを使った時の使い方を知っておきたいのです。 御経験のある方、御教示お願い致します。

  • C言語の質問です!

    #include "stdafx.h" #include <iostream> #include <string> #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <conio.h> using namespace std; double arrayMin(double array[][], int n){ double Min=9999999999999999999999.999999; for(int N=0;N<n;N++){ if(array[N][0]!=NULL&&array[N][0]<Min){ Min=array[N][0]; } } return Min; } double arrayMax(double array[][], int n){ double Max=-9999999999999999999999.999999; for(int N=0;N<n;N++){ if(array[N][0]!=NULL&&array[N][0]<Max){ Max=array[N][0]; } } return Max; } int main(){ double data[3][10] = {{2.0, 1.0, 5.0, 3.0, 2.0, 21.0, 4.0, 5.0, 4.0, 28.0}, {1.0, 1.0, 5.0, 3.0, 2.0, 21.0, 4.0, 5.0, 4.0, 28.0}, {3.0, 1.0, 5.0, 3.0, 2.0, 21.0, 4.0, 5.0, 4.0, 28.0}}; double min, max; min=arrayMin(data, 3); max=arrayMax(data, 3); printf("min = %lf, max = %lf\n", min, max); return 0; } 二次元配列の1行目の配列の最大値と最小値を求めることを考え,上のようなプログラムを書いたのですが, 1>.\maxmin.cpp(12) : error C2087: 'array' : 添字がありません。 1>.\maxmin.cpp(21) : error C2087: 'array' : 添字がありません。 1>.\maxmin.cpp(34) : error C2059: 構文エラー : ']' 1>.\maxmin.cpp(35) : error C2664: 'arrayMax' : 1 番目の引数を 'double [3][10]' から 'double [][1]' に変換できません。(新しい機能 ; ヘルプを参照) 1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 というようなエラーが出てしまいます. 途中のarray[N][0]!=NULLは二次元配列dataが3行より少ない場合に対応させています. どなたかアドバイスをいただけますでしょうか? よろしくお願いいたします!

  • 文字配列から数値への変換

    MicrosoftのVisual-Studio 2005を使っています。 C/C++については、ほぼ素人で、困っています。 下記のような簡単なソースで、 456 012 678 を表示するようにしたいのですが、できなくて困っています。 最初の 123 789 345 は下記のソースで表記できたのですが、どうすればよいの でしょう? 数値をわざと文字列で読み込んで、これを 数値に変換しているのでややこしいのかもしれませんが、 できればこれでやりたいので、申し訳ありませんが、教えていただ けないのでしょうか。よろしくお願いします。 #include "stdafx.h" #include "stdlib.h" char str[3][200] = { "123 456", "789 012", "345 678" }; int _tmain(int argc, _TCHAR* argv[]) { int a[10]; for (argc = 0; argc < 3; argc++){ a[argc] = atof(str[argc]); printf("%d\n", a[argc]); }; return 0; }

  • MacでC言語を勉強してみてるのですが

    最近C言語に興味を持って 趣味程度に、ハーバート・シルトさん著の「独習C」を、 Xcodeを使ってCが使える感じにして、 プログラミングを打って、ビルドして、コンソールで結果を見て、ふむふむ、ってやっていたのですが、 7章の4節でコマンドライン引数というものが出てきて、 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int i; double d; long l; i = atoi(argv[1]); l = atol(argv[2]); d = atof(argv[3]); printf("%d %ld %f", i, l, d); return 0; } という例題のプログラムの結果を見たいのですが、コマンドラインというものがどうすればXcodeで見られるのかよくわかりません。 ぜひ助けてください。コンソールには出ないんですよね・・・?

    • ベストアンサー
    • Mac
  • アセンブラの読み方

    お世話になります。 アセンブラを勉強しています。 下記について教えていただけないでしょうか。 よろしくお願いいたします。 1 .file 2 .data 3 var: .long 0x1234 4.text 5 .global main 6 main: 7 movb $1, %al // 値1をレジスタalに代入 8 push %eax // レジスタeaxの内容をスタックに格納 9 call IncReg // 関数呼び出し 10 pop %eax // スタックからレジスタeaxに引き出し 11 push var // 変数varの内容をスタックに格納 12 call IncReg // 関数呼び出し 13 pop %ecx // スタックからレジスタecxに引き出し 14 ret // リターン 15 IncReg: 16 movl %esp, %ebp // pushによって動いたスタックの先頭アドレスをレジスタ ebp に代入 17 movl 4(%ebp), %edx // mainから渡された eax(var) の値をレジスタ edx に代入 18 incw %edx // レジスタ edx の値を2増やす 19 movl %edx, 4(%ebp) // 2増やしたものを引数のあるスタックの場所に代入 20 ret // リターン (質問) 7 でレジスタ al に 1 を代入したのは何か意味があるのでしょうか。 17 の4(%ebp)はスタックポインタの1つ下、つまりmainから渡された引数でよろしいでしょうか。 18 の incw %edx はレジスタ edx の値を 2 増やすという意味でよろしいでしょうか。 13 でレジスタ ecx の値は 1236 になるので正しいでしょうか。

専門家に質問してみよう