2016-12-03 11 views
0

私はNASMファイルとCファイルを持っています。私のOSはUbuntu 17.04 64ビットリンクCとNASMと64ビット

私は別の投稿からの指示に従っています。

#include <stdio.h> 

int doit(int a, int b); 

int main() 
{ 
    printf("%d\n", doit(2,4)); 
    return 0; 
} 

doit.asm:

global doit 

section .data 

section .text 

doit: 

    xor rax, rax   ;sets rax to 0 

    mov eax, [rsp+8]  ;sets **b** to eax(32bit = int size) 
    add eax, [rsp+16]  ;adds **a** to eax(32bit = int size) 

    ret 

コンパイル:Linking C with NASM

ここに私のコードは

main.cのだ

[email protected]:~/Desktop/TEST$ nasm -f elf64 doit.asm && gcc -Wall main.c doit.o 
[email protected]:~/Desktop/TEST$ ./a.out 318503633 
[email protected]:~/Desktop/TEST$ 

を結果、あなたが見ることができるように偶然ではない近い6

ある予測結果に結果は32ビットのASM

+0

問題は規則を呼んでいます。 System V 64ビットABIは、[ここにあります](https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-r252.pdf)にあります。パラメータの受け渡しについては、セクション3.4.3_で説明しています。最初の6つの整数クラスのパラメータは、レジスタ_RDI _、_ RSI _、_ RDX _、_ RCX _、_ R9_、_ R8_の順に渡されます。整数クラスの結果は_RAX_で返されます。図3.4には、関数によってどのレジスタを保存する必要があるかも示されています。 2つのパラメータを追加するには、 'add rsi、rdi''、' mov rax、rsi''' retと同じくらい簡単です。 2つのレジスタを追加して3番目にセーブするトリックは 'lea rax、[rdi + rsi]' –

答えて

0

異なっている理由は、あなたがx64のパラメータに が故に、レジスタ によって渡される別の呼び出し規約を使用している、非常に簡単です教えてくださいあなたのアセンブリコードはスタック上のa、bパラメ​​ータを探しています(espを使用しています)32ビットでスタックを渡します。 これを解決するには、x64で使用される呼び出し規約を調べて、パラメータを渡すために使用され、Cコード内でそれを判断する方法 objdump -dを使用して、実際に開いていることを理解するためにコードの分解を調べてください。 O rをgcc -m32でコンパイルし、コンパイラに独自の呼び出し規約(スタック上)を使用させます。

+0

となります。32ビットx86システムV ABIは「独自仕様」ではありません。段落や句読点がないため、電話でこれを書いたと思うので、それは悪い自動修正か何かだと思います。 –

+0

ええ私は自分のPCで今すぐ利用できませんが、これが可能なときに喜んでこれを修正します – DrPrItay

1

正しい呼び出し規約を使用していません。 AMD64のLinuxはSystem V AMD64 ABIを使用します。

main.cの

#include <stdio.h> 

extern int sum (int a, int b); 

int main() 
{ 
    const int a = 2; 
    const int b = 3; 

    printf ("%d + %d = %d\n", a, b, sum (a, b)); 
    return 0; 
} 

sum.asm

 global sum 

     section .text 
sum: 
     mov eax, edi 
     add eax, esi 
     ret 

ビルド手順

nasm -f elf64 -o sum.o sum.asm 
gcc -o main.o -c main.c 
gcc -o main main.o sum.o 
+0

register-args呼び出し規約により、より効率的なコードが可能になります: 'lea eax、[rdi + rsi]'、 。 (OPのプロトタイプは引数と戻り値に 'int'を使用するので、64ビットレジスタの上位半分にあるゴミには保存/操作されません。特に、 REX接頭辞のサイズ。)(スタンドアローン関数では、次の関数の前にパディングすることは実際には両方とも16Bをとることを意味します)。 –

+0

また、x86-64.orgは死んでおり、復帰していないようです(http://stackoverflow.com/questions/18133812/where-is-the-x86-64-abi-documented)。 ABIドキュメントへのリンクについては、[x86タグwiki](http://stackoverflow.com/tags/x86/info)を参照してください。若干最近のPDFコピーを他のサイトにリンクしたい人もいます。 –

+0

オペランドサイズを変更しました。 Cのシグネチャと一致するように明示的に 'add'命令を続けました –

関連する問題