Доступ к ассемблеру из C ++ - PullRequest
5 голосов
/ 09 ноября 2011

Это мое программирование.Мне нужно выяснить самый большой среди массива целых чисел, используя метод, написанный на языке программирования 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. Но я получаю следующее: enter image description here

Здесь ясядьте и подумайте ... Разве это не значение индекса 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

Ответы [ 2 ]

7 голосов
/ 09 ноября 2011

mov si,offset a неверно.Когда у вас есть параметр функции, объявленный как int a[], функция фактически получает указатель.Поскольку вам нужно значение указателя (a), а не его адрес (&a в C, offset a в сборке), используйте mov si, a.

. Кроме того, inc si не кажется правильным- вам нужно увеличить si на sizeof(int) для каждого элемента.

Редактировать:

Вы смешиваете код C ++ (for loop, cout) со своей сборкой.Код C ++, вероятно, будет использовать те же регистры, что может привести к конфликтам.Вам следует избегать этого.

Вам также необходимо выяснить, какие регистры разрешено изменять вашей функции в соответствии с используемым соглашением о вызовах.Если вы используете какие-либо регистры, которые нельзя изменять, вам нужно push их в начале и pop их в конце.

3 голосов
/ 09 ноября 2011

Вы должны убедиться, что ваш компилятор не использует ваши регистры.Наилучшим способом было бы написать всю функцию в сборке и реализовать желаемое соглашение о вызовах (c-call или stdcall - как угодно).Затем вызовите эту функцию из C / C ++.

Однако, если вы знаете, что будете использовать только один компилятор, и как он работает, у вас не должно возникнуть проблем с использованием встроенного ассемблера, но это действительно ловушка.

...