Τετάρτη 8 Φεβρουαρίου 2023

Revision 9, Version 12

 The new revision can unload controls from forms, including controls from arrays of controls. The video show the BUTTONSONFRAME module and with some added instructions we can remove controls. Also show execution of machine code (which call back M2000 code).



This is the module BUTTONSONFRAME, with yellow is the removing command
// new version
// we can unload buttons from array
//
smooth off
declare form1 form
declare frame1 image form form1
declare frame2 image form form1
declare button1(3) button form form1 image frame1
method form1 "move",1000,1000,10000, 5000
method frame1 "move", 600,600, 10000-2*600, 4000
method frame2 "move", 600,600, 10000-2*600, 4000
integer lastindex=-1
for i=0 to 2
method button1(i), "move", 1000, 1000+1000*i, 3000, 600
next
for i=3 to 5
declare button1() over
method button1(i), "move", 4600, 1000+1000*(i-3), 3000, 600
next
max=5
with frame1, "visible" as visible, "tabstop", false
with frame2, "visible" as visible2, "tabstop", false
with form1, "LastControl" as LastControl$, "backcolor" as backcolor ' read only
Function SetTab(Where, x, s$, forecolor, tabcolor, thiscolor){
cls thiscolor
pen forecolor
double
bold 1
w=size.x(s$, fontname$, mode)
h=size.y("fj", fontname$, mode)
h1=h+twipsY*2
width 4 {
move twipsX*2, h1
draw x
draw ,-h
draw w
draw h, h
draw to scale.x-twipsX*2
draw to ,scale.y-twipsY*2
draw to twipsX*2
draw to twipsX*2,h1
}
move 100, 100
floodfill x+150, 150, tabcolor
method Where, "MaskColor", thiscolor
move X+twipsX*6, twipsY*2
italic 1
legend s$, fontname$, mode,0,0,1
=w
}
myBc=backcolor
Layer frame1{
w1=SetTab(Frame1, 0, " Frame1 ", 11, 1, myBc)
}
Module Mess(s$) {
normal
italic 0
cursor 0, height/2
report 2, s$
}
Layer frame2{
w1= SetTab(Frame2, w1+twipsX*10, " Frame2 ", 15, 2, myBc)
Mess "This is frame 2"
}
layer form1 {
cls myBc
form width, height
gradient 5, 1
Print @(0,height-1),
Print Part $(6, width),"Double click in a button and then click on frame to unload it"
}
function restroreFocus {
local s$=LastControl$
if s$<>"" then
// we use New here because the event function has same scope as the module's scope
// Control method get number of string
method form1, "Control", s$ As new UserControl
method UserControl, "SetFocus"
end if
}
function frame1.click {
print "click frame1"
method frame1,"Zorder"
call local restroreFocus()
if lastindex<>-1 then
declare button1() remove lastindex
lastindex=-1
end if
refresh


}
function frame2.click {
print "click frame2"
method frame2,"Zorder"
refresh
}
function form1.click {
print "click form1"
if visible then
visible=false
Layer frame2{
w1= SetTab(Frame2, 0, " Frame2 ", 11, 2, myBc)
Mess "This is frame 2"
}
else
refresh 1000
Layer frame1{
w1=SetTab(Frame1, 0, " Frame1 ", 15, 1, myBc)
}
Layer frame2{
w1= SetTab(Frame2, w1+twipsX*10, " Frame2 ", 11, 2, myBc)
Mess "This is frame 2"
}
layer form1 {
gradient 5, 1
Print @(0,height-1),
Print Part $(6, width),"Double click in a button and then click on frame to unload it"
}
visible=true
call local restroreFocus()
end if
refresh 10
}
function button1.click( new index) {
with button1(index), "caption" as new cap$
lastindex=index
print "("+index +") "+ cap$
refresh
}
method form1, "show", 1
declare form1 nothing



And this is the MACHINECODE2 module:

linespace 0
font "Courier New"
form 120
k=bold
bold 0
Cls #050f05, 0
pen #fff0ff
Pen 14 {Print "This is an example of machine code executing a loop calling M200 code"}
far=if(rnd>.5->false, true)
Print if$(far=true->"Using dec ecx && jnz rel32","Using loop rel8")
const clip=false // true to produce code and place it to clipboard
Print "Use this disassembler:"
Print "https://defuse.ca/online-x86-assembler.htm#disassembly2"
currency ms=monitor.stack // cast double to currency
Hex "Size in use of return stack = ";ms
Hex  "Total size of return stack (including free memory), >30MByte = ";monitor.stack.size
// Version 11 Revision 15
Buffer clear BinaryData as Long*10
Return BinaryData, 1:=500
Buffer code clear alfa as byte*1024


module beta {
print :print "done"
}
dim values(0 to 99) as long
long idx
module beta2 {
values(idx)=eval(BinaryData,0)
print values(idx),
idx++
}
flush
Pc=0
Op(0x31, 0xC0)
OpLong(0xb9, 100) ' mov ecx, 100
mLoop=pc // need that
op(0x01, 0xc8) ' add eax, ecx  (eax=eax+ecx)
OpLong(0xa3, BinaryData(0)) ' mov ds:BinaryData(0), eax  ' copy to data section


CallModule(AddressOf beta2)


if far then
op(0x49) ' dec ecx
Loop2(mLoop)
else
Loop(mLoop)  // 2 bytes (dec ecx)
end if
CallModule(AddressOf beta)
Op(0x31, 0xc0) '  zero eax
Ret(20) ' 5 long values are pushed by Execute Code.
document doc$
for i=0 to pc-1
doc$=Hex$(eval(alfa, i),1)
next
Print "Code:";doc$
Print @(tab(1))
report {
ORG 0x}+Hex$(alfa(0))+{
}+Hex$(alfa(0))+{: 31 c0                   xor    eax,eax
}+Hex$(alfa(2))+{: b9 64 00 00 00          mov    ecx,0x64 ; 100 to eax
}+Hex$(alfa(7))+{: 01 c8                   add    eax,ecx
}+Hex$(alfa(9))+{: a3 }+@hexdump(BinaryData(0))+{          mov    ds:0x}+@hexlow(BinaryData(0))+{,eax ; memory address of BinaryData(0)
}+Hex$(alfa(0xe))+{: 51                      push   ecx
}+Hex$(alfa(0xf))+{: 50                      push   eax
}+Hex$(alfa(0x10))+{: 68 }+@hexdump(AddressOf beta2)+{          push   0x}+Hex$(AddressOf beta2)+{ ; AddressOf beta2
}+Hex$(alfa(0x15))+{: e8 }+@hexdump(binary.add(module(), binary.not(alfa(0x15)+4)))+{          call   0x}+@hexlow(module())+{
}+Hex$(alfa(0x1a))+{: 58                      pop    eax
}+Hex$(alfa(0x1b))+{: 59                      pop    ecx
}+Hex$(alfa(0x1b))+{: 49                      dec    ecx
}+Hex$(alfa(0x1d))+{: 0f 85 e4 ff ff ff       jne    0x7
}+Hex$(alfa(0x23))+{: 51                      push   ecx
}+Hex$(alfa(0x24))+{: 50                      push   eax
}+Hex$(alfa(0x25))+{: 68 }+@hexdump(AddressOf beta)+{          push   0x}+Hex$(AddressOf beta)+{ ; AddressOf beta
}+Hex$(alfa(0x2a))+{: e8 }+@hexdump(binary.add(module(), binary.not(alfa(0x2a)+4)))+{          call   0x}+@hexlow(module())+{
}+Hex$(alfa(0x2f))+{: 58                      pop    eax
}+Hex$(alfa(0x30))+{: 59                      pop    ecx
}+Hex$(alfa(0x31))+{: 31 c0                   xor    eax,eax
}+Hex$(alfa(0x33))+{: c2 14 00                ret    0x14
}
print
if clip then clipboard doc$: exit
Try Ok {
profiler
Execute Code alfa, 0
print timecount
}
M=Uint(Error)
Print eval(BinaryData,0), " value at BinaryData(0)"
ms=monitor.stack
Hex "Size in use of return stack = ";ms
Print "From array values()"
print values()
print "press a key"
push key$: drop
if module(infobasic) then keyboard "infobasic", 13
bold k
End
Sub Op()
while not empty
Return alfa, pc:=number
pc++
end while
End Sub
Sub OpLong()
Return alfa, pc:=number, pc+1:=number as long
pc+=5
End Sub
Sub Ret(n=0)
if n<>0 then
Return alfa, pc:=0xC2, pc+1:=n as integer
pc+=3
else
Return alfa, pc:=0xC3
pc++
end if
End Sub
// module() return the real address of then module calling function.
// The [AddressOf modulename_something] pass as parameter to this function
// so we Push the AddressOf modulename_something
// and then we call code at address module() (using relative addressing)
// the module called like it is a part of this module (like a gosub/return structure)
Sub CallModule()
Stack New {Op(0x51, 0x50)}
Return alfa, pc:=0x68, pc+1:=number as long
pc+=5
Return alfa, pc:=0xE8, pc+1:=binary.add(module(), binary.not(alfa(pc)+4)) as long
local zz=binary.add(module(), binary.not(alfa(pc+4)))
// ? Hex$(module());" = ";Hex$(binary.add(alfa(pc), 5, zz))
// ? Hex$(module()-pc-5-alfa(0));" = ";Hex$(binary.add(module(), binary.not(alfa(pc+4))))
pc+=5
Stack New {Op(0x58, 0x59)}
End Sub
// 0xE2 cb LOOP rel8 D Valid Valid Decrement ECX ; jump short if count ≠ 0.
// 0xE1 cb LOOPE rel8 D Valid Valid Decrement ECX ; jump short if count ≠ 0 and ZF = 1.
// 0xE0 cb LOOPNE rel8 D Valid Valid Decrement ECX ; jump short if count ≠ 0 and ZF = 0.
Sub Loop()
Return alfa, pc:=0xe2, pc+1:=(number-pc-2+256)
pc+=2
End Sub
// 0x49                      dec    ecx  // OF, SF, ZF, AF, and PF flags are set according to the result.
// 0x85 jnz rel32
// by default this (number-pc-5+0xFFFFFFFF) is type of modulo 2^32  (same as binary.add())
Sub Loop2()
Return alfa, pc:=0x0F,pc+1:=0x85, pc+2:=(number-pc-5+0xFFFFFFFF) as long
pc+=6
End Sub
function hexlow(a as currency)
=lcase$(Hex$(a))
end function
function hexlowInt(a as currency)
=lcase$(Hex$(a,2))
end function
function hexdump(a as currency)
local string z=Hex$(a)
=lcase$(mid$(z,7,2)+" "+mid$(z,5,2)+" "+mid$(z,3,2)+" "+mid$(z,1,2))
end function




Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.