Ассемблер с C или C ++

0

Я должен написать программу на языках Assembly и C или C++. Основной модуль в C имеет задачу взять данные от пользователя и отобразить результаты.

В модуле сборки есть 2 процедуры.

Первый должен взять массив действительных чисел из основного модуля и вернуть среднее значение элементов массива.

Второй должен взять массив символов и один одиночный символ и вернуться к сумме основного модуля этих символов в массиве.

Например:

array:     'Kangaroo'
character: 'o'
Return 2.

Я написал это, но это не сработает. Я не знаю, что не так...

В коде C++ у меня есть:

extern "C" float average(float* tab, int G);
extern "C" int  search(int n, char a, char* arr);

И здесь все в порядке.

Но вот мой код сборки:

.386
.model SMALL,c
PUBLIC search
PUBLIC average
.stack          400h

.data

    _Result  DW  ?
     one dd 1.0

.code

search PROC

    push    bp        
    mov     bp, sp

    mov dx, 0           
    mov al, [bp+6]    
    mov cx,0           
    jmp compare

    compare:       
        cmp al, [bp+12]
        je increment
        jmp continue

    increment:
        inc cx         
        jmp continue
    continue:
        add bp, 1       
        inc dx       
        cmp dx, 100         
        jne compare  
        jmp end

   end:

    mov _Result, cx      
    mov ax, _Result      
    pop bp              
    ret 


search ENDP

average PROC

    push ebp
    mov esp,ebp

    push esi

    mov ecx, [ebp+12]
    mov esi, [ebp+8] 

    finit

    fldz 

    denominator:
    fld dword PTR one

    fld    dword PTR [esi]    

    fdivp st(1), st(0)   

    faddp st(1),st(0)

    add esi,4
    loop denominator

    pop esi
    pop ebp
    ret 

average ENDP

END 

Я использую DosBox с компилятором BorlandC. В "Среднем" я всегда получаю результат как 0 или ошибку. В "Поиск" у меня неправильный ответ.

Пожалуйста, помогите мне с этим. Спасибо.

Теги:
arrays
assembly

2 ответа

0
Лучший ответ

В вашей функции search вы сравниваете al с [bp+12]. Это работает только на первом персонаже. Когда вы добавляете в bp, вы испортили свой стек стека. [bp+12] - ваш символ *. Вам нужно переместить [bp+12] в регистр и использовать этот регистр в качестве char*. Инкремент, который регистрируется каждый раз через цикл, а не увеличивается на bp. bp должен оставаться неизменным до тех пор, пока вы не выйдете из своей функции.

Кроме того, a находится в bp+8, а не bp+6. Вам может потребоваться проверить настройки вашего компилятора, чтобы узнать, действительно ли arr на bp+12 или bp+10. Это будет зависеть от того, компилятор нажимает на символ как 2 байта или 4.

Кроме того, вы выполняете цикл 100 раз через свой массив безоговорочно. Предположительно n - это размер вашего массива, поэтому переместите его в cx и используйте cx качестве счетчика циклов.

В вашей функции sum tab находится в bp+4 а G - в bp+8. Обратите внимание, что вы получаете их (ecx и esi) от неправильных смещений.

0

Взгляните на это:

_Sum:
        push    ebp             ; create stack frame
        mov     ebp, esp
        mov     eax, [ebp+8]    ; grab the first argument
        mov     ecx, [ebp+12]   ; grab the second argument
        add     eax, ecx        ; sum the arguments
        pop     ebp             ; restore the base pointer
        ret

вам нужно настроить стек в начале и затем соответствующим образом принять аргументы из стека. Я вполне уверен, что [bp+6] в вашем коде может привести к неприятностям, потому что нет типа данных, который бы соответствовал этому смещению. Подробнее о смешивании C и сборке можно прочитать здесь: http://courses.engr.illinois.edu/ece390/books/labmanual/c-prog-mixing.html

  • 0
    Кто-то может спросить, в чем смысл сохранения и восстановления кадра стека. Вы вообще не используете стек.
  • 0
    Вы находитесь, когда вы взаимодействуете с C.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню