2

それで、最初に、これは私が手伝っている友人のための割り当てです、そして私がCをしたのでしばらく経ちますが、それは問題ではありません(または少なくとも私はそうではないと思います)、問題はアセンブリコードです。割り当てでは、インラインアセンブリで記述された関数を使用して、ユーザーが入力した後に関数に渡された2つの数値を合計し、値を返し、それを出力する必要があります。コードを実行すると、asm関数、特に2番目のmovコマンドで見つかったメモリ位置の読み取りまたは書き込みでエラーが発生し、そのコード行を実行しようとするとプログラムがハングします。プログラムをトレースすると、値の1つが正しく保存され(ユーザーが入力した2番目の値が何であれ、値はアセンブリで逆に読み取られるため、正常だと思います)、もう1つは正しく保存されません。まったく読まないと、プログラムがクラッシュします。私はこれを理解するために約4時間費やしましたが、現在は外部の支援に頼っています。とにかく、十分な背景、徹底しようとすると、ここにコードがあります。私がしていることはおそらく基本的なことであり、私を正面から見つめていると確信していますが、どんな助けでもありがたいです。そうそう、ビジュアルスタジオでmasmが有効になっていることを確認しました。

#include "stdafx.h"
#include "stdio.h"
#include <conio.h>

int sum( int val1, int val2 );
int main (void)
{
int val1=0, val2=0, val3=0;

printf("Hello, this program will add two whole numbers. Please enter the first    number.\n");
scanf("%d",&val1);

printf("Please enter the second number.\n");
scanf("%d",&val2);

val3 = sum(val1, val2);
printf("The sum of %d and %d is %d", val1, val2, val3);
_getch();

return 0;
 }

 int sum ( int val1, int val2 ){
 int val3;

    __asm{  mov eax, val2        ;
            push eax             ;
            mov ebx, val1        ;
            push ebx             ;
            add eax, ebx         ;
            mov ecx, val3        ;
            pop val3             ;
            pop ebx              ;
            pop eax              ;
            pop ecx              ;
            ret                  ;
    }
    return val3;

}
4

2 に答える 2

3

すべてのプッシュとポップが何のためにあるのかわかりませんが、これは機能します:

int sum ( int val1, int val2 )
{
    int val3;

    __asm{  mov eax, val2        ;
            mov ebx, val1        ;
            add eax, ebx         ;
            mov val3, eax        ;
         }
    return val3;
}
于 2012-11-18T22:09:50.253 に答える
0

CPUレジスタをロードするときにプッシュアンドポップを使用する必要はありません。プッシュ命令により、SS:[ESP]レジスタペアが指すメモリ位置に値が書き込まれます。ここで、SSは16ビットスタックセグメントであり、ESPは32ビットスタックポインタです。これにより、ESPがオペランドのサイズ(バイト単位)だけデクリメントされます。pop命令は逆の操作を実行し、SS:[ESP]が指すメモリ位置から読み取り、ESPをオペランドのサイズ(バイト単位)でインクリメントします。

于 2017-04-02T04:36:36.217 に答える