OberonCore
https://forum.oberoncore.ru/

Процедура Fill по аналогии с Kernel.Erase
https://forum.oberoncore.ru/viewtopic.php?f=2&t=4895
Страница 1 из 1

Автор:  Димыч [ Вторник, 17 Декабрь, 2013 08:34 ]
Заголовок сообщения:  Процедура Fill по аналогии с Kernel.Erase

Коллеги, в порте AGG часто требуется заполнение кусков массива одним байтом.
В С это реализуется процедурой fill или аналогичными.
Для ББ это весьма опасное занятие, и, по-хорошему, надо бы переписывать это через настоящее обращение к массивам, через FOR или COPY.

Однако, есть уже работающий код, который использует процедуру Fill (точнее, SYSTEM.FILL(address, value, len) из XDS-runtime).

Поэтому, я написал процедуру на ассемблере, по аналогии с Kernel.Erase:

Код:
PROCEDURE [ code ] agg_fill*(adr, words: INTEGER; val: INTEGER)
      089H, 0C7H,   (* MOV EDI, EAX *)
      031H, 0C0H,   (* XOR EAX, EAX *)
      059H,         (* POP ECX *)
      058H,         (* POP EAX *)
      0F3H, 0AAH;   (* REP STOSB *)


Процедура работает, но меня смущает то, что я вынужден был передать параметр val в виде четырехбайтного числа, потому как я не уверен, в каком виде передаются в стек параметры.

По задумке, правильный интерфейс процедуры такой:

Код:
PROCEDURE [ code ] agg_fill*(adr, words: INTEGER; val: SHORTCHAR)


больше того, она в таком виде работает правильно.

Т.е. получается, что параметры процедуры (кроме первого) передаются через приведение к 32 битам и складыванию в стек.
Как это можно уточнить? В документации я это не нашел.

Автор:  maliya [ Вторник, 17 Декабрь, 2013 10:13 ]
Заголовок сообщения:  Re: Процедура Fill по аналогии с Kernel.Erase

My version fill procedure is:

Код:
  PROCEDURE [ code ] agg_fill*(adr, size: INTEGER; val: SHORTCHAR)
     089H, 0C7H,   (* MOV EDI, EAX *)
     059H,         (* POP ECX *)
     058H,         (* POP EAX *)
     0F3H, 0AAH;   (* REP STOSB *)


and I dont known what is your question (for google translation)

Автор:  Димыч [ Вторник, 17 Декабрь, 2013 10:25 ]
Заголовок сообщения:  Re: Процедура Fill по аналогии с Kernel.Erase

maliya писал(а):
and I dont known what is your question (for google translation)


Well, I'll ask question in a different way.

There are two procedures,

Код:
PROCEDURE [ code ] agg_fill*(adr, words: INTEGER; val: INTEGER)

and
Код:
PROCEDURE [ code ] agg_fill*(adr, words: INTEGER; val: SHORTCHAR)

with the same code.

The obvious difference is the val parameter size, 4 bytes vs. 1 byte.
Since both procedures work correctly, it seems that compiler uses 4 bytes as a placeholder for parameters of smaller size.

Does my suggestion correct?
I found no info on this topic at documentation.

And you are right, it is not necessary to do XOR on EAX.

Автор:  maliya [ Вторник, 17 Декабрь, 2013 10:46 ]
Заголовок сообщения:  Re: Процедура Fill по аналогии с Kernel.Erase

I use size instead of words is for more clear meaning.(the org Kernel.Erase use words(4bytes))

Цитата:
The obvious difference is the val parameter size, 4 bytes vs. 1 byte.
Since both procedures work correctly, it seems that compiler uses 4 bytes as a placeholder for parameters of smaller size.

yes, the compile push shortchar use four bytes,
but our fill procedure use REP STOSB, that only one byet(AL(shortchar)) is used, discard the other three bytes. intel doc have this detail.

be glad you continue agg work.

Автор:  Димыч [ Вторник, 17 Декабрь, 2013 11:04 ]
Заголовок сообщения:  Re: Процедура Fill по аналогии с Kernel.Erase

maliya писал(а):
I use size instead of words is for more clear meaning.(the org Kernel.Erase use words(4bytes))

Цитата:
The obvious difference is the val parameter size, 4 bytes vs. 1 byte.
Since both procedures work correctly, it seems that compiler uses 4 bytes as a placeholder for parameters of smaller size.

yes, the compile push shortchar use four bytes,
but our fill procedure use REP STOSB, that only one byet(AL(shortchar)) is used, discard the other three bytes. intel doc have this detail.

be glad you continue agg work.


I use REP STOSB advisedly.
It should fill memory with 1 byte pattern.

Thanks for help!

Автор:  Jordan [ Вторник, 17 Декабрь, 2013 15:33 ]
Заголовок сообщения:  Re: Процедура Fill по аналогии с Kernel.Erase

Димыч писал(а):
PROCEDURE [ code ] agg_fill*(adr, words: INTEGER; val: INTEGER)
      089H, 0C7H,   (* MOV EDI, EAX *)
      031H, 0C0H,   (* XOR EAX, EAX *)
      059H,         (* POP ECX *)
      058H,         (* POP EAX *)
      0F3H, 0AAH;   (* REP STOSB *)


Такой ассемблер я видел в turbo pascalях старых версий. На ББ можно писать на внятном ассемблере(как в комментариях)?

И ещё вопрос, неужели данную функцию нельзя написать на КП, без асма?

Автор:  Иван Кузьмицкий [ Вторник, 17 Декабрь, 2013 15:57 ]
Заголовок сообщения:  Re: Процедура Fill по аналогии с Kernel.Erase

Джордан, а вы можете читать доку сначала - перед задаванием вопросов, а не после? :)

Автор:  Димыч [ Вторник, 17 Декабрь, 2013 16:04 ]
Заголовок сообщения:  Re: Процедура Fill по аналогии с Kernel.Erase

Jordan писал(а):
Димыч писал(а):
PROCEDURE [ code ] agg_fill*(adr, words: INTEGER; val: INTEGER)
      089H, 0C7H,   (* MOV EDI, EAX *)
      031H, 0C0H,   (* XOR EAX, EAX *)
      059H,         (* POP ECX *)
      058H,         (* POP EAX *)
      0F3H, 0AAH;   (* REP STOSB *)


Такой ассемблер я видел в turbo pascalях старых версий. На ББ можно писать на внятном ассемблере(как в комментариях)?

И ещё вопрос, неужели данную функцию нельзя написать на КП, без асма?

На первый вопрос ответ отрицательный. Можно только в опкодах.

На второй вопрос тоже отрицательный ответ. Дело в архитектуре AGG. Там часто используются куски массивов, причем начало этого массива вычисляется. Я и так по возможности заменил адресную арифметику индексной, но, к сожалению, это не везде удалось. К версии 2.0 порта, думаю, можно это будет исключить, а пока прямая работа с памятью оказалась проще, чем борьба с типами, увы.

Автор:  Valery Solovey [ Воскресенье, 22 Декабрь, 2013 00:21 ]
Заголовок сообщения:  Re: Процедура Fill по аналогии с Kernel.Erase

Насколько я помню, в стек складываются данные фиксированного размера. Логично предположить, что этот размер соответствует размеру слова. Для 32-разрядных архитектур это будет 4 байта. Это зашито в процессор.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/