Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| | |
Работа с локальными переменными и Call 20.11.01 11:03 Число просмотров: 1097
Автор: Chingachguk <Chingachguk> Статус: Member
|
> push bp > mov bp,sp > xor ax,ax > call 5C29:02CD > ...тело... > нельзя ли 4уть подробней(и 4то делает call 5C29:02CD)?
1)
xor ax,ax
call 5C29:02CD - Это проверка размера стека;
Компили с ключом {$S-} и она исчезнет ;)
2)
Ниже пример работы с локальными переменными в процедуре на Пасе:
Процедура может:
Const
ZeroNumStr = 0; - Поместить в конец строки ноль;
CutString = 1; - Отрезать пробелы справа;
LeftString = 2; - Сдвинуть строку влево;
RightString = 3; - Сдвинуть строку вправо.
Procedure StringOperation( var ProcStr,DestStr; Operation: Byte);
Const
MaxActionNumber = 3;
Var
WorkDest: String;
Begin
Asm
pusha
push ds
lds si,ProcStr
push ss
pop es
lea bx,WorkDest
cld
lodsb
xor ah,ah
test ax,ax
jz @@Done {Exit if Lenght Source = 0}
mov cx,ax
mov es:[bx],ah {Lenght String = 0}
lea di,[bx+1]
push offset @@Done {Put return address}
mov ax,word ptr Operation
cmp al,MaxActionNumber {Invalid Number ?}
jbe @@GoodAction
retn {Exit without any action !}
@@GoodAction:
push bx
mov bx,ax
shl ax,2
add ax,bx {ax = Procedure Number*5}
pop bx
add ax,offset @@Jmps
jmp ax
@@Jmps:
mov ax,offset @@ZeroNumString
jmp ax
mov ax,offset @@CutString
jmp ax
mov ax,offset @@LeftString
jmp ax
mov ax,offset @@RightString
jmp ax
@@ZeroNumString:
mov es:[bx],cl {Lenght Dest = Lenght Source}
pusha
rep movsb {Dest = Source}
popa
@@ZeroFill:
lodsb
cmp al,' '
jnz @@ZeroDone
mov al,'0'
stosb
loop @@ZeroFill
@@ZeroDone:
retn
@@CutString: {Cut Fillers in right part of String}
mov es:[bx],cl {Lenght Dest = Lenght Source}
push cx
rep movsb {Dest = Source}
pop cx
@@CutFill:
dec si
cmp byte ptr [si],' '
jnz @@CutDone
dec byte ptr es:[bx]
loop @@CutFill
@@CutDone:
retn
@@LeftString:
xor ah,ah {Set Flag}
@@LeftFill:
lodsb
test ah,ah
jnz @@FillUnCond
cmp al,' '
jz @@SkipFiller
@@FillUnCond:
stosb
inc byte ptr es:[bx]
mov ah,1
@@SkipFiller:
loop @@LeftFill
retn
@@RightString:
@@RightFill:
loop @@RightFill
retn
@@Done:
les di,DestStr
push ss
pop ds
lea si,WorkDest
lodsb
stosb
xor ah,ah
test ax,ax
jz @@NullResult
mov cx,ax
rep movsb
@@NullResult:
pop ds
popa
End;
End;
|
<programming>
|
[PAS&ASM]непонятное слово в переда4е параметров. 19.11.01 18:12
Автор: kar Статус: Незарегистрированный пользователь
|
трабл такой:
пишу процедуру на пасе и ее debug'y...полу4ается такая хрень...
procedure xyz(var x:byte; y:integer; z:byte);
...
пушутся два слова(естесвенно seg,ofs),затем еще по слово
(зна4ения y и z) и еще одно - ip
теперь главное: пушется BP(и скорее всего для некого "leave")
затем естественно ret.
таки вот - 4е за leave push bp???
|
|
[PAS&ASM]непонятное слово в переда4е параметров. 19.11.01 19:13
Автор: Cyril <sc> Статус: Member
|
> трабл такой: > пишу процедуру на пасе и ее debug'y...полу4ается такая > хрень... > > procedure xyz(var x:byte; y:integer; z:byte); > ... > пушутся два слова(естесвенно seg,ofs),затем еще по слово > (зна4ения y и z) и еще одно - ip > > теперь главное: пушется BP(и скорее всего для некого > "leave") > затем естественно ret. > > таки вот - 4е за leave push bp???
приблизительно все должно выглядеть так:
push bp
mov bp,sp - для доступа к параметрам процедуры
enter ... - место под локальные переменные...
........................
leave - освобождает память
---
|
| |
...уто4нение 19.11.01 20:01
Автор: kar Статус: Незарегистрированный пользователь
|
> > трабл такой: > > пишу процедуру на пасе и ее debug'y...полу4ается такая > > хрень... > > > > procedure xyz(var x:byte; y:integer; z:byte); > > ... > > пушутся два слова(естесвенно seg,ofs),затем еще по > слово > > (зна4ения y и z) и еще одно - ip > > > > теперь главное: пушется BP(и скорее всего для некого > > "leave") > > затем естественно ret. > > > > таки вот - 4е за leave push bp??? > > приблизительно все должно выглядеть так: > > push bp
> mov bp,sp - для доступа к параметрам процедуры
> enter ... - место под локальные переменные...
> ........................
> leave - освобождает память
> ---
картина такая:
...
push bp
mov bp,sp
xor ax,ax
call 5C29:02CD
...тело...
leave
ret 8
несовсем понятно "с доступом к параметрам proc" и leave.
-вообще-то (если я правильно тя понял...) параметры пихаются
в стек и освобождаются они оттуда 4ерез ret с параметром.
нельзя ли 4уть подробней(и 4то делает call 5C29:02CD)?
|
| | |
...уто4нение 20.11.01 11:26
Автор: Cyril <sc> Статус: Member Отредактировано 20.11.01 11:31 Количество правок: 1
|
> картина такая: > ...
доступ к параметрам [bp+2] = z, [bp+4] = y, [bp+6] = address(x)
[bp-...] доступ к локальным параметрам процедуры
> push bp > mov bp,sp
в компилере указана опция StackChecking
так вот это оно самое и есть
> xor ax,ax > call 5C29:02CD
> ...тело...
Если отключишь 286 инструкции то leave исчезнет
Я думаю это должно прояснить ситуацию c leave
enter imm16, 0 286+ push bp ENTER is always slower
mov bp, sp and 4 bytes in length
sub sp, imm16 if imm16 = 0 then push/mov
is smaller
leave 486+ mov sp, bp LEAVE is only 1 byte
pop bp long and is faster
on the 186-386. The
mov esp, ebp MOV/POP is much faster
pop ebp on 486 and Pentium
---
> leave
выталкиваем параметры процедуры и ip
> ret 8 > > несовсем понятно "с доступом к параметрам proc" и leave. > -вообще-то (если я правильно тя понял...) параметры > пихаются > в стек и освобождаются они оттуда 4ерез ret с параметром. > > нельзя ли 4уть подробней(и 4то делает call 5C29:02CD)? >
|
| | |
Работа с локальными переменными и Call 20.11.01 11:03
Автор: Chingachguk <Chingachguk> Статус: Member
|
> push bp > mov bp,sp > xor ax,ax > call 5C29:02CD > ...тело... > нельзя ли 4уть подробней(и 4то делает call 5C29:02CD)?
1)
xor ax,ax
call 5C29:02CD - Это проверка размера стека;
Компили с ключом {$S-} и она исчезнет ;)
2)
Ниже пример работы с локальными переменными в процедуре на Пасе:
Процедура может:
Const
ZeroNumStr = 0; - Поместить в конец строки ноль;
CutString = 1; - Отрезать пробелы справа;
LeftString = 2; - Сдвинуть строку влево;
RightString = 3; - Сдвинуть строку вправо.
Procedure StringOperation( var ProcStr,DestStr; Operation: Byte);
Const
MaxActionNumber = 3;
Var
WorkDest: String;
Begin
Asm
pusha
push ds
lds si,ProcStr
push ss
pop es
lea bx,WorkDest
cld
lodsb
xor ah,ah
test ax,ax
jz @@Done {Exit if Lenght Source = 0}
mov cx,ax
mov es:[bx],ah {Lenght String = 0}
lea di,[bx+1]
push offset @@Done {Put return address}
mov ax,word ptr Operation
cmp al,MaxActionNumber {Invalid Number ?}
jbe @@GoodAction
retn {Exit without any action !}
@@GoodAction:
push bx
mov bx,ax
shl ax,2
add ax,bx {ax = Procedure Number*5}
pop bx
add ax,offset @@Jmps
jmp ax
@@Jmps:
mov ax,offset @@ZeroNumString
jmp ax
mov ax,offset @@CutString
jmp ax
mov ax,offset @@LeftString
jmp ax
mov ax,offset @@RightString
jmp ax
@@ZeroNumString:
mov es:[bx],cl {Lenght Dest = Lenght Source}
pusha
rep movsb {Dest = Source}
popa
@@ZeroFill:
lodsb
cmp al,' '
jnz @@ZeroDone
mov al,'0'
stosb
loop @@ZeroFill
@@ZeroDone:
retn
@@CutString: {Cut Fillers in right part of String}
mov es:[bx],cl {Lenght Dest = Lenght Source}
push cx
rep movsb {Dest = Source}
pop cx
@@CutFill:
dec si
cmp byte ptr [si],' '
jnz @@CutDone
dec byte ptr es:[bx]
loop @@CutFill
@@CutDone:
retn
@@LeftString:
xor ah,ah {Set Flag}
@@LeftFill:
lodsb
test ah,ah
jnz @@FillUnCond
cmp al,' '
jz @@SkipFiller
@@FillUnCond:
stosb
inc byte ptr es:[bx]
mov ah,1
@@SkipFiller:
loop @@LeftFill
retn
@@RightString:
@@RightFill:
loop @@RightFill
retn
@@Done:
les di,DestStr
push ss
pop ds
lea si,WorkDest
lodsb
stosb
xor ah,ah
test ax,ax
jz @@NullResult
mov cx,ax
rep movsb
@@NullResult:
pop ds
popa
End;
End;
|
|
|