Последние записи
- Перенести программу из Delphi в Lazarus
- Определить текущую ОС
- Автоматическая смена языка (раскладки клавиатуры)
- Сравнение языков на массивах. Часть 2
- wprintf как напечатать кириллицу
- Взаимодействие через командную строку
- Сравнение языков на массивах. Часть 1
- Сравнение языков по скорости
- Чтение огромных xml-файлов
- Как в Python+Selenium webdriver открыть новую вкладку в уже открытом браузере?
Интенсив по Python: Работа с API и фреймворками 24-26 ИЮНЯ 2022. Знаете Python, но хотите расширить свои навыки?
Slurm подготовили для вас особенный продукт! Оставить заявку по ссылке - https://slurm.club/3MeqNEk
Online-курс Java с оплатой после трудоустройства. Каждый выпускник получает предложение о работе
И зарплату на 30% выше ожидаемой, подробнее на сайте академии, ссылка - ttps://clck.ru/fCrQw
29th
Авг
Способы передачи параметров в подпрограммы в Delphi
Posted by obzor under Delphi
Почему деление на 0?
Function ProbelsInStr(const s:string128; const c:char; const chastota, nachalo:byte):ShortString;
asm
mov ecx, 0
mov cl, chastota
push ebx
push edi
push esi
mov edi, result
mov esi, s
mov eax, 0
mov al, [esi]
mov edx, 0
div ecx
pop esi
pop edi
pop ebx
end;
Почему на «div ecx» выдаёт ошибку деления на ноль?
Почему после такого кода
mov ecx, 0
mov cl, chastota
в cl ноль, а не chastota ?
Наверное все дело в типе вызова (register), когда параметры передаются через регистры. Вы попросту стираете передаваемое значение присваивая mov ecx, 0. После этого команда mov cl, castota, которая по факту превращается в mov cl, cl (см. в окне ассемблера, предварительно остановив исполнение программ на этой команде), ничего не заносит в регистр cl.
Чтобы в будущем не натыкаться на эти проблемы, тогда стоит указывать тип вызова не использующий для передачи параметров регистры. Например:
Function ProbelsInStr(const s:string128; const c:char; const chastota, nachalo:byte):ShortString; stdcall; // передавать параметры через стек
Некоторые отправились в процедуру через регистры, а некоторые через оперативку
Вопрос: можно ли как-то в строке процедуры задать какую переменную как конкретно передавать и какую в какой регистр отправлять?
И можно ли 2 переменных типа байт, или чар через один регистр передать?
Только если напишите свой способ вызова через ассемблерную вставку как inline процедуру.
Задавая названия вызовов выбирать можно из стандартных способов: [pascal], cdecl, register, stdcall
[] — тип вызова по умолчанию, задавать это название нет необходимости.
Как правило тип вызова определяет порядок передачи аргументов и буфер для их передачи, а также еще вариант очистки от аргументов.
Например stdcall отличается от cdecl только тем, что в последнем аргументы из стека очищает вызвавшая подпрограмма. А первый тип предполагает, что эту очистку выполнит вызванная процедура.
Но в обоих вызовах аргументы передаются через стек в обратном порядке (сначала последний).
Только обычно хватает перечисленных стандартных типов, а вот возня со своим типом вызова обычно требуется только для совместимости с нестандартными библиотеками (например, cdecl добавлен для программ написанных на C/C++; он так и расшифровывается C declaration). Для всех остальных случаев хватает 4-х перечисленных.
То есть, я правильно понял? Эта метка означает, что все переменные будут идти через регистры?
Function FilterStr255(const StrIn, StrFilter: ShortString):ShortString; register;
Нет. Только первые 3. Остальные через стек. Но в приведенном примере — все
еще safecall — я забыл о нем упомянуть.
Похожие статьи
Купить рекламу на сайте за 1000 руб
пишите сюда - alarforum@yandex.ru
Да и по любым другим вопросам пишите на почту
пеллетные котлы
Пеллетный котел Emtas
Наши форумы по программированию:
- Форум Web программирование (веб)
- Delphi форумы
- Форумы C (Си)
- Форум .NET Frameworks (точка нет фреймворки)
- Форум Java (джава)
- Форум низкоуровневое программирование
- Форум VBA (вба)
- Форум OpenGL
- Форум DirectX
- Форум CAD проектирование
- Форум по операционным системам
- Форум Software (Софт)
- Форум Hardware (Компьютерное железо)