2017-05-05 18 views
0

私は8086emuを使ってテストしたが、100%で動作したが、Visual Studioで間違った結果とエラーを出した。任意のアイデアやこの問題を解決する方法。与えられた配列のCアセンブリエラー

マイコード: -

#include "stdafx.h" 
#include <iostream> 
using namespace std; 


void main(void) 
{ 
short *arr; 
arr = new short[10]; 
cout << "please enter the array elements" << endl; 
for (int i = 0; i < 10; i++) 
{ 
    cin >> arr[i]; 
} 

short *p; 
p = arr; 
_asm{ 

START: 
    mov cx, 9 
     mov esi, p 

    LABEL2 : 
    MOV ax, [esi] 
     CMP ax, [esi + 2] 
     JGE LABEL1 
     MOV bx, [esi + 2] 
     MOV word ptr[esi], bx 
     MOV word ptr[esi + 2], ax 
     JMP START 

    LABEL1 : 
    inc esi 
     inc esi 
     LOOP LABEL2 

} 

for (int i = 0; i < 10; i++) 
{ 
    cout << arr[i] << endl; 
} 

} 

The result

+1

それがどこまで組み立てスルーを作るん:

ソリューションは、完全なECXレジスタを初期化するのですか?あなたはこれをデバッグするために何をしましたか? –

+0

@PaulBentley私はそれをデバッグしていません、それは配列要素を入力した直後に現れますが、ASMブロック内の同じコードはMasmとemuで動作します。 –

+0

'loop'はおそらく下位の単語(' cx')だけでなく 'ecx'を減らしてチェックします。 'mov cx、9'の代わりに' mov ecx、9'をすればどうでしょうか? – Michael

答えて

0

問題がa commentでマイケルによって解決されています。

問題は、暗黙的にデクリメントしてECXレジスタをテストするLOOP instructionを使用していたことです。しかし、ループの先頭でレジスタを初期化したとき、その下位ワード(mov cx, 9)のみを初期化し、上位ワードにガーベジを残しました。 mov ecx, 9

+0

ところで、 'LOOP'は非常に遅く、時代遅れの命令です。あなたは本当にそれを全く使ってはいけません。これは 'dec ecx' +' jnz ??? 'と同じで、代わりに使うべきものです。そのように書いたのであれば、コードがより速くて慣用的であるだけでなく、このバグも簡単に理解できます。 (しかし、もっと一般的には、インラインアセンブリをここに書くべきではありません。これは、Cコンパイラが簡単に生成して最適化できるコードです。アセンブリコードは遅く、エラーが発生しやすくなります。 *アセンブリ言語プログラミング、Cコンパイラを使用しないでください) –

+0

@CodyGrayああ、ありがとう、私はそれを念頭に置くでしょうが、なぜ私はCコンパイラを使用すべきではありませんか? –

+0

アセンブリ言語を習得したい場合は、MASMやNASMのようなアセンブラを使用し、アセンブリのコードをすべて*書く*。インラインアセンブリーは恐ろしい、複雑な獣であり、アセンブリを学ぶ良い方法ではありません。 –

関連する問題