5

これは私のプログラミング課題です。8086 プログラミング言語で記述されたメソッドを使用して、整数の配列の中で最大のものを見つける必要があります。これは私の試みです:

  #include <iostream.h>
    #include <conio.h>

    int returnLargest(int a[])
    {
        int max;
        asm mov si,offset a

        for(int i=0;i<6;i++) //Assuming six numbers in the array...Can be set to a variable 'n' later
        {
              asm mov ax,[si]
              asm mov max,ax
              asm inc si
              cout<<max<<"\n";    //Just to see what is there in the memory location
        }

        asm mov si,offset a
        asm mov cx,0000h

        asm  mov dx, [si]

            asm mov cx,06h

        skip: asm   mov si,offset a
        asm mov bx,[si]
        asm        mov max,bx
        asm inc si
        abc: asm   mov bx,max
           asm     cmp [si],bx
        asm jl ok
           asm     mov bx,[si]
              asm  mov max,bx
        ok: asm loop abc
        asm mov ax,max
        return max;
    }
    void main()
    {
        clrscr();
        int n;
        int a[]={1,2,3,4,5,6};
        n=returnLargest(a);
        cout<<n; //Prints the largest
        getch();
    }

予想される答えは

1 2 3 4 5 6 6.しかし、私が得るのはこれです:ここに画像の説明を入力

ここで私は座って考えます... 実際にメモリに格納されている配列のインデックス i の値ではないでしょうか? 少なくとも、a[i] が 12 (たとえば) の場合、i 番目のメモリ位置には 12 という数字が書き込まれていると教えられたからです。

または、値がメモリ位置に保存されていない場合、目的のタスクを達成するためにメモリ位置に書き込むにはどうすればよいですか?

また、これらの概念をブラッシュアップするために、ネット/ペーパーバックの資料をリンクしてください。

編集 :

アセンブリ内の同じコードは問題なく動作します...

data segment
    a   db  01h,02h,03h,04h,05h,06h,'$'
    max db  ?
data ends

code segment
    start:
        assume cs:code,ds:data
        mov ax,data
        mov ds,ax

        mov si,offset a
        mov cx,0000h

        back:   mov dl,byte ptr [si]
                cmp dl,'$'
        je skip
        inc cx
                inc si
        jmp back

    skip:   mov si,offset a
                mov bl,byte ptr[si]
                mov max,bl
        inc si
        abc:    mov bl,max
                cmp [si],bl
        jl ok
                mov bl,[si]
                mov max,bl
    ok: loop abc
        mov al,max
        int 03h
code ends
    end start
4

2 に答える 2

7

mov si,offset a 間違っている。関数パラメーターをとして宣言するint a[]と、関数は実際にポインターを受け取ります。アドレス( C、アセンブリ)aではなくポインタ値()が必要なため、を使用します。&aoffset amov si, a

さらに、inc si正しくないようです-要素ごとに増やす必要siがあります。sizeof(int)

編集:

C ++コード(forループ、cout)をアセンブリと混合しています。C ++コードは同じレジスタを使用する可能性が高く、競合が発生します。これは避けてください。

また、使用する呼び出し規約に従って関数を変更できるレジスタを見つける必要があります。変更が許可されていないレジスタを使用する場合はpush、最初にそれらを変更popし、最後にそれらを変更する必要があります。

于 2011-11-09T16:14:21.920 に答える
3

コンパイラがレジスタを使用しないようにする必要があります。最善の方法は、関数全体をアセンブリで記述し、目的の呼び出し規約 (c-call または stdcall - 何でも) を実装することです。次に、その関数を C/C++ から呼び出します。

ただし、使用するコンパイラが 1 つだけであることと、それがどのように機能するかがわかっている場合は、アセンブラをインライン化しても問題はありませんが、実際には落とし穴です。

于 2011-11-09T16:09:58.183 に答える