Помощь - Поиск - Пользователи - Календарь
Полная версия: Не могу получить адрес массива :(
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ассемблер
-Shaienn-
Здравствуйте, есть

программа

{в ней}

функция, которая работает с массивом и в этой функции
я пытаюсь сделать такую вещь:

asm    
lea si,d
lodsw
cmp ax,3
je @m
jmp @exit
@m :
push si
lea si,e
lodsw
mov bx,ax
lodsw
mul bx
mov di,si
sub di,4
stosw
mov ax,0
stosw
@exit:
end;


т.е на паскале:

case d[i] of
3: begin e[i]:=e[i]*e[i+1];
e[i+1]:=0; end;
end;


проблема в том, что я с адреса, полученного командой lea, командой lodsw не получаю число из массива (массив integer), но если пишу на тот же адрес, то в массив все записывается nea.gif

отдельным куском данный код на ассемблере работает... Где может быть косяк?
Могу дать файл программы, но она большая.... Но все равно, может кто поможет.
Ассемблер изучаю один день, так что нужна помощь.
-Shaienn-
d: array [1..100] of integer
e: array [1..100] of integer

прога смешанная, паскаль и асм
volvo
Цитата
Могу дать файл программы
Только присоедини его к сообщению, а не копируй текст, если он большой (для этого, возможно, придется зарегистрироваться...)
Виталий Шевченко
Так и не смог я под своим нормальным именем зарегистрироваться, чего-то накосячил (модераторы, может сотрете из базы ник Shaienn)

Вот прога, основная суть - интерпретатор команд, пишешь ручками функцию, прога рисует график.
Данный кусок кода в функции xvalue

xvalue вычисляет значение для функции, т.е. я задаю например cos(2*x), и функция xvalue "распознает" эти 2*x и вычисляет.
Malice
Цитата(-Shaienn- @ 10.11.2006 16:34) *

проблема в том, что я с адреса, полученного командой lea, командой lodsw не получаю число из массива (массив integer), но если пишу на тот же адрес, то в массив все записывается nea.gif

Возможно это из-за того, что stosw пишет по ES:DI, а lodsw c DS:SI, а у тебя в этот момент сегменты разные.
Виталий Шевченко
Цитата(Malice @ 10.11.2006 17:32) *

Возможно это из-за того, что stosw пишет по ES:DI, а lodsw c DS:SI, а у тебя в этот момент сегменты разные.


А как сегменты организовать одинаково? А то я думал, что получаю смещение и дальше не важно читаю, пишу ли...

прикрепил программку, данный код отдельным куском... все работает sad.gif
Malice
Цитата(Виталий Шевченко @ 10.11.2006 18:17) *

А как сегменты организовать одинаково?

asm
push ds {Запомним ds, вдруг он паскалю нужен был}
push es
pop ds {ds=es}
.... твой код
pop ds {Восстановим ds}
...
end;


Примерно так.
Виталий Шевченко
Цитата(Malice @ 10.11.2006 20:11) *

asm
push ds {Запомним ds, вдруг он паскалю нужен был}
push es
pop ds {ds=es}
.... твой код
pop ds {Восстановим ds}
...
end;


Примерно так.



Ага, зашибись smile.gif
Спасибо
Виталий Шевченко
а можно еще вопрос, как мне из real массива вытащить вещественное число и загнать его в st(0)?
Malice
Цитата(Виталий Шевченко @ 10.11.2006 20:59) *

а можно еще вопрос, как мне из real массива вытащить вещественное число и загнать его в st(0)?

Думаю его надо сначала преобразовать из REAL в DOUBLE, a потом FLD ..
Виталий Шевченко
Цитата(Malice @ 11.11.2006 10:35) *

Думаю его надо сначала преобразовать из REAL в DOUBLE, a потом FLD ..



{$N+}
program as3;
var d: array [1..100] of integer;
e: array [1..100] of double;
r:integer;
begin
r:=10;
d[1]:=3;
e[2]:=4.4;
e[1]:=2.3;
asm
mov dx,0
lea si,d
lodsw
cmp ax,3
je @m
jmp @exit
@m :

finit
lea si,e
fld dword ptr[si]
fld dword ptr[si+8] {double в памяти 8 байт?}
fmul
lea di,d
fstp dword ptr[di]
@exit:
end;
writeln(e[1]);
writeln(2*4.4);
readln;
end.



он в массив записывает чушь какую-то, подскажите, что я неправильно делаю?
FreeMan
хм. практически все smile.gif
во первых - сам написал, что double 8байт, а пишем dword ptr, а не qword ptr. дальше - результат записываешь в массив d, а выводишь число из массива е...
finit
lea si,e
fld qword ptr[si]
fld qword ptr[si+8] {double в памяти 8 байт?}
fmul
lea di,d
fstp qword ptr[si]
Виталий Шевченко
я вас, наверное, уже достал глупыми вопросами, но можно ли обнулить ячейку массива более простым способом?


asm
push es
pop ds
lea si,d
lodsw
cmp ax,3
je @m
jmp @exit
@m :
finit
lea si,e
fld qword ptr[si]
fld qword ptr[si+8]
fmul
fstp qword ptr[si]
push ds --------- вот я ее обнуляю
pop es
lea di,e
add di,8
mov ax,0
mov cx,4
rep stosw ---------вот ноль в ячейке
@exit:
end;
Виталий Шевченко
Написал я ассемблерную часть, но криво, у меня паскаль вылетает в винду с недопустимой операцией...
Посмотрите плиз, в чем дело... Очень надо...
FreeMan
Ну сначала
asm
lea di,s
mov cx,100
mov ax,0
rep stosw
lea di,t
mov cx,100;еще на 4 умножить тогда в самый раз, думаю
mov ax,0
rep stosw;массив s вроде double, а это значит, что ты его не совсем до конца обнуляешь.
;но в принципе можно нулями и не забивать, обычно там и так нули
end;

такой же код есть в xvalue
это из того, что сразу бросилось в глаза. дальше не разберался. пока нет времени
Виталий Шевченко
И все же, есть какие-нить нюансы добавления ассемблерных вставок?
Просто, если я ставлю {$R+}, то паскаль пишет Range check error и вылетает....
Без ассемблерной части все работает, так что вывод - косяк в ассемблере. Проверьте плиз.

e: array [1..100] of double;
d: array [1..100] of integer;

asm
mov mm,0
lea si,d
@beg:
add mm,1
push ss
pop ds
lodsw
cmp ax,0
je @exit
cmp ax,1
je @beg
cmp ax,2
je @beg
push ax
push si
pop di
push ds
pop es
sub di,2
mov ax,0
stosw
mov cx,100
sub di,2
rep movsw
finit
lea si,e
mov ax,mm
mov bx,8
mul bx
mov bx,si
add bx,ax
fld qword ptr[bx-8]
fld qword ptr[bx]
pop ax
cmp ax,3
je @m
cmp ax,4
je @d
@m:
fmul
jmp @c
@d:
fdiv
jmp @c
@c:
fstp qword ptr[bx-8]
push ds
pop es
push bx
pop di
mov ax,0
mov cx,4
rep stosw
mov cx,400
push di
pop si
sub di,8
rep movsw
jmp @beg
@exit:
lea si,d
push es
pop ds
lodsw
cmp ax,0
je @end
push ax
push si
pop di
sub di,2
mov ax,0
stosw
mov cx,100
sub di,2
rep movsw
finit
lea si,e
fld qword ptr[si]
fld qword ptr[si+8]
pop ax
cmp ax,1
je @a
cmp ax,2
je @s
@a:
fadd
jmp @con
@s:
fsub
jmp @con
@con:
fstp qword ptr[si]
push ds
pop es
push si
pop di
mov ax,0
mov cx,4
rep stosw
mov cx,400
push di
pop si
sub di,8
rep movsw
jmp @exit
@end:
end;
Malice
Асм вставка это часть процедуры ? Приведи полный код, а то мне не понятны такие моменты:

push ss {испортил ds, или прочитал параметр из стека..}
pop ds
lodsw
....
push ds {теперь es тоже равен ss}
pop es

push ds {зачемто опять..}
pop es
Т.е. в прошлый раз комбинация push ds/pop es помогла т.к. в ds уже был загружен (паскалем) нужный сегмент, это не значит, что если ты ее повторяешь, то опять все будет хорошо.
Виталий Шевченко

{
в функцию передается значение переменной x, строка с
функцией и позиция, с которой распознаем
}
function xvalue(x:double;i:integer;s1:string):double;
var
j,mm,x3,code:integer;
c:char;
s2:string;
e: array [1..100] of double;
d: array [1..100] of integer;
begin


asm
lea di,d
mov cx,100
mov ax,0
rep stosw
lea di,e
mov cx,400
mov ax,0
rep stosw
end;
mm:=1;
x3:=1;
repeat
i:=i+3;
{эта программа вычисляет значение аргумента функции, т.е если, например,
sin(2*x+2) то именно эта часть распознает и вычисляет значение в скобках,
а i:=i+3 это три буквы функции s,i и n в строке s1, в которой хранится вся функция}

c:=s1[i];
until c=#40; {(}
repeat
i:=i+1;
c:=s1[i];
if (c<=#57) and (c>=#47) then
begin
j:=i;
repeat
i:=i+1;
c:=s1[i];
until (c>#57) or (c<#48) or (c=' ');
s2:=copy(s1,j,i-j);
val(s2,e[mm],code);
mm:=mm+1;
c:=s1[i];
end;

if (c<=#47) and (c>=#42) then
begin
case c of
'+':d[x3]:=1;
'-':d[x3]:=2;
'*':d[x3]:=3;
'/':d[x3]:=4;
end;
x3:=x3+1;
end;

if c='x' then
begin
e[mm]:=x;
mm:=mm+1;
end
until c=#41; {)}

asm
mov mm,0
lea si,d
@beg:
add mm,1
push ss
pop ds
lodsw
cmp ax,0
je @exit
cmp ax,1
je @beg
cmp ax,2
je @beg
push ax
push si
pop di
push ds
pop es
sub di,2
mov ax,0
stosw
mov cx,100
sub di,2
rep movsw
finit
lea si,e
mov ax,mm
mov bx,8
mul bx
mov bx,si
add bx,ax
fld qword ptr[bx-8]
fld qword ptr[bx]
pop ax
cmp ax,3
je @m
cmp ax,4
je @d
@m:
fmul
jmp @c
@d:
fdiv
jmp @c
@c:
fstp qword ptr[bx-8]
push ds
pop es
push bx
pop di
mov ax,0
mov cx,4
rep stosw
mov cx,400
push di
pop si
sub di,8
rep movsw
jmp @beg
@exit:
lea si,d
push es
pop ds
lodsw
cmp ax,0
je @end
push ax
push si
pop di
sub di,2
mov ax,0
stosw
mov cx,100
sub di,2
rep movsw
finit
lea si,e
fld qword ptr[si]
fld qword ptr[si+8]
pop ax
cmp ax,1
je @a
cmp ax,2
je @s
@a:
fadd
jmp @con
@s:
fsub
jmp @con
@con:
fstp qword ptr[si]
push ds
pop es
push si
pop di
mov ax,0
mov cx,4
rep stosw
mov cx,400
push di
pop si
sub di,8
rep movsw
jmp @exit
@end:
end;
xvalue:=e[1];
end;


А с чтением ds из ss, когда я ставлю параметр компилирования R+, то адрес, по которому надо читать масссив почему-то находится не в es а в ss.... а в es что-то иное.... если этого параметра не ставлю, то адрес в es нормальный...
И если я загружаю разные массивы мне что, не нужно обновлять сегмент памяти?
FreeMan
ты вот всякою фигню с ds, es мутишь, а восстанавливать сегментные регистры - одно из правил кодинга на асме.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.