Как передать значение переменной в стек (Ассемблер)?
Здравствуйте.
Решаю задачу на ассемблере TASM. Подпрограмма, которая вычисляет гиперболический синус. Эта подпрограмма должна быть связана с главной программой с использованием стандартов связи с языком С.
Моя проблема заключается в том, что я не могу загрузить вещественное число в стек.
Я ввожу число с клавиатуры, это число находиться в стеке FPU, засовываю ее в переменную Source, а потом я должен загрузить его в стек и вызвать подпрограмму, где я его выгружаю и начинаю вычисления
Вот примерный код:
---------------
Source dq ?
Result dq ?
---------------
sub sp,16
mov bp,sp
fstp Source
mov qword ptr [bp], Source //тут ошибка "need register in expression"
mov qword ptr [bp+8], Result //тут ошибка "need register in expression"
call OutFloat
Add sp,16
---------------
Т.е. можно выгружать значение из сопроцессора прямо в то место, где будет исходящий параметр для вызова функции.
Ошибка возникает из-за того, что нет команд mov пересылающих значение из памяти в память.
Я тоже так делал. Но у меня в лабе дано задание - подпрограмма принимает значение двух аргументов (Source, Result). Поэтому подумал, что есть способ отправить в стек две переменные.
jcmvbkbc,Спасибо за примеры.Можно задать еще вопросы? В 3 способе, как в подпрограмме вызвать значение в стек FPU?
Я пробовал так, но программа вывела 0 FLD qword ptr [di]
А в 1 способе я не понял, что происходит. И он еще не работает, при компилировании выдает ошибку: "Illegal indexing mode" в строчке fstp qword ptr [sp]
3 способ понятен, но тут тоже возникают сложности с загрузкой этой переменной в стек FPU. По идее нужно вызвать три раза pop, отложить их где-то и объединить в единое число?
push bp
mov bp, sp
fld qword ptr [bp + 8]
...
pop bp
ret
А в 1 способе я не понял, что происходит. И он еще не работает, при компилировании выдает ошибку: "Illegal indexing mode" в строчке
В первом способе я перекладываю double из source на стек через сопроцессор. Да, я забыл что 16-битный ассемблер не умеет идексировать относительно sp. Должно быть так:
push bp
mov bp, sp
sub sp, 8
fld qword ptr [source]
fstp qword ptr [bp - 8]
call OutFloat
add sp, 8
pop bp
ret
3 способ понятен, но тут тоже возникают сложности с загрузкой этой переменной в стек FPU. По идее нужно вызвать три раза pop, отложить их где-то и объединить в единое число?
Нет. Они лежат на стеке в правильном порядке. Это уже готовое число. Его можно загрузить тем же самым кодом:
push bp
mov bp, sp
fld qword ptr [bp + 8]
...
pop bp
ret
push AX ; передать значение регистра AX в стек
push ВX ; передать значение регистра BX в стек
.... ; ваш код
pop BX ; извлечь значение из стека в регистр AX
pop AX ; извлечь значение из стека в регистр AX
Если вы отправляете несколько значений в стек и вынимаете их от туда, то нужно это делать по принципу LIFO (последний пришел, первый вышел)
То есть я должен загрузить вещественное число в AX, потом с помощью push засунуть с стек и в подпрограмме вызвать с помощью pop. Ну тогда возникает вопрос как загрузить вещ. число в AX?
А мой код с созданием с указателем bp и стеком sp не работает?