Курсовая работа: Конкатенація строк Assembler
LOCAL str3[15] :BYTE
arithm proc є оголошенням функція, тобто текстом, який каже, зо почалась функція, яка має бути викликаною десь у коді. Наступний текст – оглошення локальних змінних, що є особливістю компілятора. Тільки у MASM 32 можна створити локальні змінні, які розташовуються у стеку. Доступ до цих змінних виконується за допомогою ADDR, тобто макроса, який повертає їх адрес розташування у стеку. Також хочеться особливо відмітити LOCAL hInput :DWORD . Ця змінна потрібна, щоб організувати консольний ввод змінних та строк. Розмір змінної два слова. Змінна LOCAL hOutPut :DWORD також тримає хендл, але для консольного вивода. Змінні LOCAL nRead1 :DWORD LOCAL nRead2 :DWORD мають однакове призначення, тобто воні використовують у однієї і тієїж функції. У них записується результат зчитування строки з консолі, тобто кількість байт, яка була прочитана.
Для того щоб реалізувати вивод та ввод у програмі потрібно спочатку отримати хендли для ввода та вивода, тобто проініціалізувати змінні LOCAL hOutPut :DWORD LOCAL hInput :DWORD. Це робиться завдяки
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov hOutPut, eax
invoke GetStdHandle, STD_INPUT_HANDLE
mov hInput , eax
Функція GetStdHandle , яка отримає аргумент STD_OUTPUT_HANDLE розташовує у регістрі eax хендл для вивода тексти у консоль. mov hOutPut, eax ініціалізує змінну hOutPut. Такая ж операція робиться для hInput але з метою отримати хендл для вивода.
invoke szLen, offset strNum1
invoke WriteConsole, hOutPut, offset strNum1, eax, NULL, NULL
invoke ReadConsole, hInput , ADDR str1, 10d, ADDR nRead1, NULL
Функція szLen отримує як аргумент строку з сегменту даних, щоб знайти її длину, яка розташовуєть у регістрі eax. Функція WriteConsole використовується для вивода на консоль. Нижче приведен її прототип, взяти з MSDN.
BOOL WriteConsole(HANDLE hConsoleOutput, // handle to screen bufferCONST VOID *lpBuffer, // write bufferDWORD nNumberOfCharsToWrite, // number of characters to writeLPDWORD lpNumberOfCharsWritten, // number of characters writtenLPVOID lpReserved // reserved);Наступна функція ReadConsole , яка вводе строку str1. Її прототип також приведен нижче.
BOOL ReadConsole(HANDLE hConsoleInput, // handle to console input bufferLPVOID lpBuffer, // data bufferDWORD nNumberOfCharsToRead, // number of characters to readLPDWORD lpNumberOfCharsRead, // number of characters readLPVOID lpReserved // reserved);Бачимо, що у цих двух фунціях використовуються змінні, які були пояснені раніше, тобто добре пояснення не потрібне тепер. Треба пояснити код, який використовує бібліотечні функції
invoke StrToFloat, ADDR str1, offset a
Ця функція має за мету перевод строки у змінну формата qword, яка може потім бути використаною FPU. Перейдемо тепер до основного коду функція, до коду, який обчислює функцію.
fld b
fld a
fcom y
fstsw ax
sahf
jz Divide
fxch
fcom y
fstsw ax
sahf jz Divide
fld b загружає до стека FPU значення змінної b. fcom y зрівнює цю змінну з нулем, fstsw ax sahf повертає флагі, яки булі загублені під час перевірки. jz Divide робить умовний перехід на метку Divide, якщо операнд буде рівен нулю. Це робиться для того, щоб уникнути ділення на нуль. Далі йде
ffree st(1)
ffree st(0)