Я должен написать программу на языках 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 или ошибку. В "Поиск" у меня неправильный ответ.
Пожалуйста, помогите мне с этим. Спасибо.
В вашей функции 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
) от неправильных смещений.
Взгляните на это:
_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