ARM-linux: непорядок с указателями

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Artlav
незнакомец
Сообщения: 6
Зарегистрирован: 30.05.2006 23:27:37
Откуда: Москва

ARM-linux: непорядок с указателями

Сообщение Artlav »

Пример программы:

Код: Выделить всё

program tst;
uses sysutils;
var rammem:array of byte;
i:integer;

function gmb(addr:dword):pbyte;
begin result:=@rammem[addr]; end;
function gmw(addr:dword):pword;
begin result:=@rammem[addr]; end;
function gmd(addr:dword):pdword;
begin result:=@rammem[addr]; end;

begin
setlength(rammem,1024*1024);
for i:=0 to 1024*1024-1 do rammem[i]:=random(256);
writeln(´st=´,inttohex(dword(@rammem[0]),4));

writeln(´1.1=´,inttohex(gmb($F0000)^,1));
writeln(´1.2=´,inttohex(gmb($F0001)^,1));
writeln(´1.3=´,inttohex(gmb($F0002)^,1));
writeln(´1.4=´,inttohex(gmb($F0003)^,1));
writeln(´2.1=´,inttohex(gmw($F0000)^,2));
writeln(´2.2=´,inttohex(gmw($F0001)^,2));
writeln(´2.3=´,inttohex(gmw($F0002)^,2));
writeln(´2.4=´,inttohex(gmw($F0003)^,2));
writeln(´4.1=´,inttohex(gmd($F0000)^,4));
writeln(´4.2=´,inttohex(gmd($F0001)^,4));
writeln(´4.3=´,inttohex(gmd($F0002)^,4));
writeln(´4.4=´,inttohex(gmd($F0003)^,4));
end.


Скомпилированная для x86 она выдаёт правильный вывод:
st=830040
1.1=F0000=1=7A
1.2=F0001=1=4A
1.3=F0002=1=8E
1.4=F0003=1=26
2.1=F0000=2=4A7A
2.2=F0001=2=8E4A
2.3=F0002=2=268E
2.4=F0003=2=626
4.1=F0000=4=268E4A7A
4.2=F0001=4=6268E4A
4.3=F0002=4=FB06268E
4.4=F0003=4=AFB0626

Но, скомпилированная для ARM она выдаёт ерунду:
st=40048020
1.1=F0000=1=7A
1.2=F0001=1=4A
1.3=F0002=1=8E
1.4=F0003=1=26
2.1=F0000=2=4A7A
2.2=F0001=2=4A7A
2.3=F0002=2=268E
2.4=F0003=2=268E
4.1=F0000=4=268E4A7A
4.2=F0001=4=7A268E4A
4.3=F0002=4=4A7A268E
4.4=F0003=4=8E4A7A26

Что-то не то с указателями в FPC для ARM-linux - невозможен доступ о адресам не кратным размеру указателя.
С-эквивалент программы работат нормально, так что это не от аппаратуры.

Что делать, как чинить?
SovNarKom
постоялец
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:

Сообщение SovNarKom »

Artlav
Запостить в мантиссу, но сначала поискать уже в открытых багах, и уж совсем сначала сказать что за верися FPC... помнится мне в SVN что-то пробегало про ARM недавно.

http://www.freepascal.org/mantis
Artlav
незнакомец
Сообщения: 6
Зарегистрирован: 30.05.2006 23:27:37
Откуда: Москва

Сообщение Artlav »

В уже открытых ничего подобного не нашел, новый добавил.
Версия 2.0.0 То же самое и в 1.9.8.
Sniper
постоялец
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение Sniper »

Вот нашёл:

2006-05-27 08:52 florian r3691
/trunk/compiler/arm/: cpupara.pas
* method pointers are now passed by value, fixes #5736
оно?

Скачай файл (http://svn.freepascal.org/svn/fpc/trunk ... pupara.pas) и должно быть счастье )
Юра
постоялец
Сообщения: 163
Зарегистрирован: 25.05.2005 10:20:09
Откуда: Украина, Киев

Сообщение Юра »

Вообще-то в ARM-е нельзя обращаться к word или dword по адресу, не кратному 4. ОС может эмулировать обращения к памяти по кривым адресам (скорее всего в линухе такая эмуляция есть), но это тормозно. Поэтому рекомендую переделать свою программу с учетом этого. Тогда все будет работать.
Artlav
незнакомец
Сообщения: 6
Зарегистрирован: 30.05.2006 23:27:37
Откуда: Москва

Сообщение Artlav »

cpupara.pas заменил, перекомпилировал, проверил. Исполняемые файлы побайтно одинаковые (кроме даты компилятора).
Не то.

Пытаюсь скомпилировать 2.1.1, пока выдаёт непонятные ошибки в RTL.

Программа - эмулятор 16 битной платформы, принцип доступа к памяти в нём по указателям в массив байтов. Это всё с нуля переписывать надобно.

Почему тогда в С всё работает?
Как производится перехват кривых адресов - компилятор что-то впутывает, или исключение какое-нибудь?
Юра
постоялец
Сообщения: 163
Зарегистрирован: 25.05.2005 10:20:09
Откуда: Украина, Киев

Сообщение Юра »

При обращении по кривому адресу валится исключение. ОС или компилятор может вставить спец обработчик, который побайтово прочитает/запишет word или dword. FPC такого обработчика не ставит.

Даже если такой обработчик есть, то полагаться на него не стоит, т.к. программа будет тормозить. Лучше написать программу сразу правильно.
Ответить