flat assembler
Message board for the users of flat assembler.

flat assembler > Programming Language Design > Pointer Arithmetic: *EDI++=*ESI--

Author
Thread Post new topic Reply to topic
codestar



Joined: 25 Dec 2014
Posts: 254
Example:
Code:
let (i8) eax=*esi++ let (u8) *ecx++=*edi++ let (i16) *edx--=eax let (u32) *edi++=*esi--
Let Arithmetic:
Code:
macro let p match a==&b, p lea a, b else match a==b, p mov a, b else match a>>>b, p sar a, b else match a<<b, p shl a, b else match a>>b, p shr a, b else match a&b, p and a, b else match a|b, p or a, b else match a+b, p if b=1 inc a else add a, b end if else match a-b, p if b=1 dec a else sub a, b end if else match a*b, p if b=2 shl a, 1 else if b=4 shl a, 2 else if b=8 shl a, 3 else imul a, b end if else match a/b, p if b=2 sar a, 1 else if b=4 sar a, 2 else if b=8 sar a, 3 else match =eax, a push edx cdq idiv pop edx else error 'Destiny must be eax' end match end if else error 'Invalid expression',\ ': let ', `p end match end macro ; upgrade let to support: a=1, b=2, c=3 macro let p& irp x, p let x end irp end macro
Get Type Size & Sign
Code:
; from type cast, return size and sign ; in globals macro get_type_p type local size, sign size=0 sign=0 match =u32, type size=32 else match =i32, type size=32 sign=1 else match =u16, type size=16 else match =i16, type size=16 sign=1 else match =u8, type size=8 else match =i8, type size=8 sign=1 else error `type, ' - Unknown type' end match its_size=size its_sign=sign end macro
Load & Store Pointer:
Code:
; get_p eax, [edi], '+' ; eax=*edi++ macro get_p a, b, c local size, sign size=its_size sign=its_sign if size=32 mov a, b else if size=16 if sign=1 movsx a, word b else movzx a, word b end if else if size=8 if sign=1 movsx a, byte b else movzx a, byte b end if else error 'Invalid size' end if match [r], b if c='+' add r, size/8 else if c='-' sub r, size/8 end if end match end macro ; get_p eax, (i8) *ebx++ macro get_p a, p& match (t) q, p get_type_p t match *z, q match r++, z get_p a, [r], '+' else match r--, z get_p a, [r], '-' else get_p a, [r], 0 end match end match end match end macro ; set_p eax, [edi], '+' ; *edi++=eax macro set_p a, b, c local size, sign size=its_size sign=its_sign if size=32 mov dword b, a else if size=16 if a=eax mov b, ax else if a=ecx mov b, cx else if a=edx mov b, dx else if a=ebx mov b, bx end if else if size=8 if a=eax mov b, al else if a=ecx mov b, cl else if a=edx mov b, dl else if a=ebx mov b, bl end if end if match [r], b if c='+' add r, size/8 else if c='-' sub r, size/8 end if end match end macro ; set_p eax, (i8) *ebx++ macro set_p a, p& match (t) q, p get_type_p t match *z, q match r++, z set_p a, [r], '+' else match r--, z set_p a, [r], '-' else set_p a, [r], 0 end match end match end match end macro
Pointer Arithmetic:
Code:
; upgrade let to support pointers. ; alters ebx if *m=*m macro let p& irp q, p match (t) c, q match *a==*b, c get_p ebx, (t) *b set_p ebx, (t) *a else match a==*b, c get_p a, (t) *b else match *a==b, c set_p b, (t) *a end match else let p end match end irp end macro
Example: 4 lines
Code:
let (i8) eax=*esi++ let (u8) *ecx++=*edi++ let (i16) *edx--=eax let (u32) *edi++=*esi--
Output: 12 lines, 300%
Code:
0FBE06 MOVSX EAX,BYTE PTR [ESI] 81C601000000 ADD ESI,0x1 0FB61F MOVZX EBX,BYTE PTR [EDI] 81C701000000 ADD EDI,0x1 8819 MOV BYTE PTR [ECX],BL 81C101000000 ADD ECX,0x1 668902 MOV WORD PTR [EDX],AX 81EA02000000 SUB EDX,0x2 8B1E MOV EBX,DWORD PTR [ESI] 81EE04000000 SUB ESI,0x4 891F MOV DWORD PTR [EDI],EBX 81C704000000 ADD EDI,0x4


Last edited by codestar on 12 Jun 2015, 16:55; edited 1 time in total
Post 31 May 2015, 09:58
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15870
Location: 162173 Ryugu
Can I ask why you chose the asterisk (*) instead of the more usual assembly style square brackets ([])?

[edi++] = [esi++] Question

Also, how does the code decide to use EBX? It becomes a hidden used register which makes it easy to forget that it is corrupted.

What about changing ADD REG,1 to INC REG?
Post 01 Jun 2015, 01:41
View user's profile Send private message Visit poster's website Reply with quote
codestar



Joined: 25 Dec 2014
Posts: 254
Quote:
revolution: Can I ask why you chose the asterisk (*) instead of the more usual assembly style square brackets ([])?

[edi++] = [esi++] Question
Standard notation. I didn't choose it, C chose it, and it's one of the few choices available in FASMG:
Code:
[edi++]=[esi++] ; wrong [edi]++=[esi]++ ; right, get value first
Quote:
Also, how does the code decide to use EBX?
Any register can be used. This is merely an example. ebx is the last register index (#3) that you can access the 8+16BIT sections of (BX/BH/BL), leaving eax-edx available to the programmer.

Now, may I ask you a question? What makes you think you're a "programmer" when you never write code and can't understand simple things? YOu can't teach an old dog new tricks. Answer: revolution is just a fake who comes online and pretends to have programming abilities which he can't prove. After 12,767 posts, he has never created one single program by himself. What little code he writes is so illogical and easy to improve in 5 seconds. Why follow their stupid rules - which have gotten them NOWHERE - unless you want to be like them and have no programs?

I challenge anyone to improve my code:
Code:
while c, c=*p++, endw, p-s, p-- while s<e, c=*s, *s++=*e, *e--=c, endw if n=0, *p++='0', *p=0 return s end loop n, c=*s++, *p++=c if c=0, break, end endl, p-- while c, c=*s++, *p++=c, endw, p-- while c=d, c=*p++, d=*s++ if c=0, break, end if d=0, break, end endw, p=c, p-d while n, x=n, x&1, x+'0' . *p++=x, n>>>1 endw, *p=0 forever, c=*p++ if c=0, return n, end . x=n, x<<2, n+x, n+n . n-'0', n+c endfv ; draw bit/byte function draw.bit, n, x, y if n draw.image bit1.i, x, y else draw.image bit0.i, x, y end endf function draw.byte, n, x, y locals i . i=8 loop i, r0=n, r1=i . r1--, r0>>cl, r0&1 draw.bit r0, x, y . x+BIT.W endl endf ; draw pixel function draw.pixel, x, y, c alias p=r0, z=r1 try clip.pixel x, y vga.xy x, y . z=c, (u32) *p=z endf 1 ; draw horizontal line function draw.line.h, x, y, n, c alias p=r0, z=r1, w=r2 . p=&x, z=&y, w=&n try clip.line 0, p, z, w vga.xy x, y . z=c loop n, (u32) *p++=z, endl endf 1 ; draw solid rectangle function draw.box, x, y, w, h, c locals i try visible x, y, w, h . i=y, i-- loop h, i++ draw.line.h x, i, w, c endl endf 1 ; draw scanline function draw.scanline, pixels, x, y, w alias p=r0, s=r1 vga.xy x, y . s=pixels loop w, (u32) *p++=*s++, endl endf 1 ; draw 8BPP scanline/bitmap with palette function draw.scanline.8, pixels, x, y, w alias p=r0, s=r1, c=r2, q=r3 vga.xy x, y . s=pixels loop w, q=*s++, q*4, q+palette.p . (u32) c=*q, (u32) *p++=c endl endf 1 function draw.bitmap.8, pixels, x, y, w, h locals i, p try visible x, y, w, h . i=y, i--, p=pixels loop h, i++ draw.scanline.8 p, x, i, w . r0=w, p+r0 endl endf 1 function draw.my.numbers locals i, n, y . i=bits.h, y=404 loop i, r0=my.numbers, r0+i, r0-- . r0=*r0, n=r0 draw.byte n, 4, y . y-BIT.H endl endf function draw.title.scene draw.text help.t, 16, 130 draw.byte magic.n, 50, 300 endf function draw.play.scene draw.board draw.my.numbers endf function draw.pause.scene draw.text pause.t, 16, 130 draw.byte magic.n, 50, 300 endf function draw.game.over print t, game.over.t, score draw.text t, 44, 170 draw.byte magic.n, 50, 300 endf ; convert 32BIT binary number to text function b2t, n, t alias p=r0, x=r1 . p=t if n=0, *p++='0', *p=0 return end while n, x=n, x&1, x+'0' . *p++=x, n>>>1 endw, *p=0 text.reverse t endf ; text.copy a, b - standard copy with ; 0 after. return advanced address function text.copy, a, b alias p=r0, s=r1, c=r2 . p=a, s=b, c=1 while c, c=*s++, *p++=c, endw, p-- endf ; text.copy.n a, b, n - copy with maximum ; size specified. return & function text.copy.n, a, b, n alias p=r0, s=r1, c=r2 . p=a, s=b loop n, c=*s++, *p++=c if c=0, break, end endl, p-- endf ; text.go t, n - advance to line # function text.go, t, n loop n try t=text.find t, 0Dh . t+2 endl endf t ; text.skip.0 a - skip 0s, return address or 0 function text.skip.0, a alias p=r0, c=r1 . p=a, c='0' while c='0', c=*p++, endw, p-- if c=0, return 0, end endf ; convert text to 32BIT binary function t2b, t alias p=r0, c=r1, n=r2 try text.skip.0 t . n=0 loop, c=*p++ if c=0, return n, end . n<<1, n-'0', n+c endl endf function draw.my.text, t, x, y locals p, n get n=text.n t . p=t loop n, r0=p, r0=*r0 draw.my.c r0, x, y, WHITE . x+r0, x+4, p++ endl endf function randomize.puzzle locals q, n alias p=r0, x=r1 . q=puzzle, n=(MAP.W*MAP.H) loop n get x=get.random . p=q, (u32) *p=x, q+4 endl endf function is.solved locals n alias p=r0, x=r1 . p=puzzle, n=(MAP.W*MAP.H) loop n, (u32) x=*p++ if x<>NORMAL, return 0, end endl endf 1 function draw.puzzle locals x, y . y=0 while y<8, x=0 while x<8 . r0=x, r0*TILE.W, r0+MAP.X . r1=y, r1*TILE.H, r1+MAP.Y draw.piece x, y, r0, r1 . x++ endw . y++ endw endf function on.key if key.event='c' if scene=SCENE.TITLE . scene=SCENE.PLAY go .draw end if scene=SCENE.GAME.OVER go .reset end if key='r' .reset: reset.game go .draw end if key='p' .pause: if scene=SCENE.PLAY . scene=SCENE.PAUSE else.if scene=SCENE.PAUSE . scene=SCENE.PLAY end go .draw end .draw: render end endf function on.mouse locals r if mouse.event='c' . r0=&close.i.x if.select r0 exit end if scene=SCENE.TITLE reset.game . scene=SCENE.PLAY go .draw end if scene=SCENE.PLAY if.select puzzle.box get.select.xy get r=get.piece.rotate \ select.x, select.y . r++ set.piece.rotate \ select.x, select.y, r go .draw end end if scene=SCENE.SOLVED reset.game . scene=SCENE.TITLE go .draw end .draw: render end endf
Post 01 Jun 2015, 02:57
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15870
Location: 162173 Ryugu
codestar wrote:
Quote:
revolution: Can I ask why you chose the asterisk (*) instead of the more usual assembly style square brackets ([])?

[edi++] = [esi++] Question
Standard notation. I didn't choose it, C chose it, and it's one of the few choices available in FASMG:
Code:
[edi++]=[esi++] ; wrong [edi]++=[esi]++ ; right, get value first
Okay, so standard for C. But not standard for assembly.

I also find the ++ notation for C to be ambiguous. Without the actual parsing rules being stated there can be other ways to interpret it.

[esi++]: increment ESI after getting the memory address for reading?

[esi]++: increment the memory at [esi] after reading it?
Post 01 Jun 2015, 09:20
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6872
Location: Kraków, Poland
revolution wrote:
Okay, so standard for C. But not standard for assembly.

I also find the ++ notation for C to be ambiguous. Without the actual parsing rules being stated there can be other ways to interpret it.?
That's exactly what I wanted to say. I think the bracket notation is much more clear, and in this case less ambiguous.
Post 01 Jun 2015, 14:09
View user's profile Send private message Visit poster's website Reply with quote
codestar



Joined: 25 Dec 2014
Posts: 254
Your argument is basically, "X is not a real X-Tian. I think X is clearer than Y but I don't know why and can't give reasons". Who cares? I'm a programmer, period, and I believe in writing good code in Abakis, C/C++, ASM, Javascript, doesn't matter which language. What is "good" code? Whatever works. "The right way is the way that works".

Tomasz:

On all keyboards I've used, * is easier to type than []. No one can argue logically that 2 inaccessible symbols [] is better to use than *. I don't see the ambiguity that you're referring to. Please clarify. In C, *(p++) means advance pointer by its size first then get *(value) after: add [p], size | mov x, type [p]. And p[i] means p[i*size] due to automatic scale. [ means +. array[i*s] = [array+i*s].
Quote:
Opinion: X is clearer than Y (based on "I don't know but I believe")
Fact: X is standard, X requires less characters than Y. To type X requires less energy (based on numbers, real evidence)


Last edited by codestar on 12 Jun 2015, 17:02; edited 1 time in total
Post 01 Jun 2015, 18:30
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15870
Location: 162173 Ryugu
codestar wrote:
On my good day, I can beat Tomasz at programming, but on his good day, he can beat me.
We're not here to "beat" each other. We're to help each other.
Post 01 Jun 2015, 22:18
View user's profile Send private message Visit poster's website Reply with quote
codestar



Joined: 25 Dec 2014
Posts: 254
It's harmless fun like kids playing video games. Since 2001/2-ish, I've always thought that Tomasz was a good programmer and I remember when vid first presented his FASMLIB which inspired me. Show me a better way so that I can learn. It's frustrating to hear people say "You're wrong" but they don't show me a right way.

Who is "we"? Speak for yourself. Personally, I write all code for my own satisfaction and development then I put it online with the hopes that it will help *advanced* programmers. I know that some people (sleepS, JohnS, they're everywhere) will misinterpret it as "Look at me, I'm so great, better than you" (nonsense).
Post 02 Jun 2015, 01:46
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 2004-2018, Tomasz Grysztar.

Powered by rwasa.