Я пытаюсь изучать программирование встроенной сборки в Delphi, и с этой целью я нашел эту статью очень полезной.
Теперь я хочу написать ассемблерную функцию, возвращающую длинную строку, в частности AnsiString
(для простоты). Я написал
function myfunc: AnsiString;
asm
// eax = @result
mov edx, 3
mov ecx, 1252
call System.@LStrSetLength
mov [eax + 0], ord('A')
mov [eax + 1], ord('B')
mov [eax + 2], ord('C')
end;
Пояснение:
Функция, возвращающая строку, имеет невидимый параметр var result: AnsiString
(в данном случае), поэтому в начале функции eax
должен содержать адрес полученной строки. Затем я устанавливаю edx
и ecx
на 3 и 1252 соответственно, а затем вызываю System._LStrSetLength
. По сути, я делаю
_LStrSetLength(@result, 3, 1252)
, где 3 - новая длина строки (в символах = байты), а 1252 - стандартная windows-1252 кодовая страница.
Затем, зная, что eax
является адресом первого символа строки , я просто установил строку в "ABC". Но это не работает - это дает мне бессмысленные данные или EAccessViolation. В чем проблема?
Обновление
Теперь у нас есть две вроде бы работающие реализации myfunc
, одна из которых использует NewAnsiString
, а другая - LStrSetLength
. Я не могу не задаться вопросом, верны ли они оба, в том смысле, что они не портят внутреннюю обработку строк в Delphi (подсчет ссылок, автоматическое освобождение и т.