flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > Programming Language Design > Pointer Arithmetic: *EDI++=*ESI--

Author
Thread Post new topic Reply to topic
codestar



Joined: 25 Dec 2014
Posts: 254
Pointer Arithmetic: *EDI++=*ESI--
Example:

Code:
let (i8eax=*esi++
let (u8) *ecx++=*edi++
let (i16) *edx--=eax
let (u32) *edi++=*esi--

Let Arithmetic:

Code:
macro let p
  match a==&bp
    lea ab
  else match a==bp
    mov ab
  else match a>>>bp
    sar ab
  else match a<<bp
    shl ab
  else match a>>bp
    shr ab
  else match a&bp
    and ab
  else match a|bp
    or ab
  else match a+bp
    if b=1
      inc a
    else
      add ab
    end if
  else match a-bp
    if b=1
      dec a
    else
      sub ab
    end if
  else match a*bp
    if b=2
      shl a1
    else if b=4
      shl a2
    else if b=8
      shl a3
    else
      imul ab
    end if
  else match a/bp
    if b=2
      sar a1
    else if b=4
      sar a2
    else if b=8
      sar a3
    else
      match =eaxa
        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 xp
    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 sizesign
  size=0
  sign=0
  match =u32type
    size=32
  else match =i32type
    size=32
    sign=1
  else match =u16type
    size=16
  else match =i16type
    size=16
    sign=1
  else match =u8type
    size=8
  else match =i8type
    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 abc
  local sizesign
  size=its_size
  sign=its_sign
  if size=32
    mov ab
  else if size=16
    if sign=1
      movsx aword b
    else
      movzx aword b
    end if
  else if size=8
    if sign=1
      movsx abyte b
    else
      movzx abyte b
    end if
  else
    error 'Invalid size'
  end if
  match [r], b
    if c='+'
      add rsize/8
    else if c='-'
      sub rsize/8
    end if
  end match
end macro

; get_p eax, (i8) *ebx++

macro get_p ap&
  match (tqp
    get_type_p t
    match *zq
      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 abc
  local sizesign
  size=its_size
  sign=its_sign
  if size=32
    mov dword ba
  else if size=16
    if a=eax
      mov bax
    else if a=ecx
      mov bcx
    else if a=edx
      mov bdx
    else if a=ebx
      mov bbx
    end if
  else if size=8
    if a=eax
      mov bal
    else if a=ecx
      mov bcl
    else if a=edx
      mov bdl
    else if a=ebx
      mov bbl
    end if
  end if
  match [r], b
    if c='+'
      add rsize/8
    else if c='-'
      sub rsize/8
    end if
  end match
end macro

; set_p eax, (i8) *ebx++

macro set_p ap&
  match (tqp
    get_type_p t
    match *zq
      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 qp
    match (tcq
      match *a==*bc
        get_p ebx, (t) *b
        set_p ebx, (t) *a
      else match a==*bc
        get_p a, (t) *b
      else match *a==bc
        set_p b, (t) *a
      end match
    else
      let p
    end match
  end irp
end macro

Example: 4 lines

Code:
let (i8eax=*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: 15302
Location: Bigweld Industries
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 cc=*p++, endwp-sp--

while s<ec=*s, *s++=*e, *e--=cendw

if n=0, *p++='0', *p=0
  return s
end

loop nc=*s++, *p++=c
  if c=0breakend
endlp--

while cc=*s++, *p++=cendwp--

while c=dc=*p++, d=*s++
  if c=0breakend
  if d=0breakend
endwp=cp-d

while nx=nx&1x+'0'
  . *p++=xn>>>1
endw, *p=0

foreverc=*p++
  if c=0return nend
  . x=nx<<2n+xn+n
  . n-'0'n+c
endfv

; draw bit/byte

function draw.bitnxy
  if n
    draw.image bit1.ixy
  else
    draw.image bit0.ixy
  end
endf

function draw.bytenxy
  locals i
  . i=8
  loop ir0=nr1=i
    . r1--, r0>>clr0&1
    draw.bit r0xy
    . x+BIT.W
  endl
endf

; draw pixel

function draw.pixelxyc
  alias p=r0z=r1
  try clip.pixel xy
  vga.xy xy
  . z=c, (u32) *p=z
endf 1

; draw horizontal line

function draw.line.hxync
  alias p=r0z=r1w=r2
  . p=&xz=&yw=&n
  try clip.line 0pzw
  vga.xy xy
  . z=c
  loop n, (u32) *p++=zendl
endf 1

; draw solid rectangle

function draw.boxxywhc
  locals i
  try visible xywh
  . i=yi--
  loop hi++
    draw.line.h xiwc
  endl
endf 1

; draw scanline

function draw.scanlinepixelsxyw
  alias p=r0s=r1
  vga.xy xy
  . s=pixels
  loop w, (u32) *p++=*s++, endl
endf 1

; draw 8BPP scanline/bitmap with palette

function draw.scanline.8pixelsxyw
  alias p=r0s=r1c=r2q=r3
  vga.xy xy
  . s=pixels
  loop wq=*s++, q*4q+palette.p
    . (u32c=*q, (u32) *p++=c
  endl
endf 1

function draw.bitmap.8pixelsxywh
  locals ip
  try visible xywh
  . i=yi--, p=pixels
  loop hi++
    draw.scanline.8 pxiw
    . r0=wp+r0
  endl
endf 1

function draw.my.numbers
  locals iny
  . i=bits.hy=404
  loop ir0=my.numbersr0+ir0--
    . r0=*r0n=r0
    draw.byte n4y
    . y-BIT.H
  endl
endf

function draw.title.scene
  draw.text help.t16130
  draw.byte magic.n50300
endf

function draw.play.scene
  draw.board
  draw.my.numbers
endf

function draw.pause.scene
  draw.text pause.t16130
  draw.byte magic.n50300
endf

function draw.game.over
  print tgame.over.tscore
  draw.text t44170
  draw.byte magic.n50300
endf

; convert 32BIT binary number to text

function b2tnt
  alias p=r0x=r1
  . p=t
  if n=0, *p++='0', *p=0
    return
  end
  while nx=nx&1x+'0'
    . *p++=xn>>>1
  endw, *p=0
  text.reverse t
endf

; text.copy a, b - standard copy with
; 0 after. return advanced address

function text.copyab
  alias p=r0s=r1c=r2
  . p=as=bc=1
  while cc=*s++, *p++=cendwp--
endf

; text.copy.n a, b, n - copy with maximum
; size specified. return &

function text.copy.nabn
  alias p=r0s=r1c=r2
  . p=as=b
  loop nc=*s++, *p++=c
    if c=0breakend
  endlp--
endf

; text.go t, n - advance to line #

function text.gotn
  loop n
    try t=text.find t0Dh
    . t+2
  endl
endf t

; text.skip.0 a - skip 0s, return address or 0

function text.skip.0a
  alias p=r0c=r1
  . p=ac='0'
  while c='0'c=*p++, endwp--
  if c=0return 0end
endf

; convert text to 32BIT binary

function t2bt
  alias p=r0c=r1n=r2
  try text.skip.0 t
  . n=0
  loopc=*p++
    if c=0return nend
    . n<<1n-'0'n+c
  endl
endf

function draw.my.texttxy
  locals pn
  get n=text.n t
  . p=t
  loop nr0=pr0=*r0
    draw.my.c r0xyWHITE
    . x+r0x+4p++
  endl
endf

function randomize.puzzle
  locals qn
  alias p=r0x=r1
  . q=puzzlen=(MAP.W*MAP.H)
  loop n
    get x=get.random
    . p=q, (u32) *p=xq+4
  endl
endf

function is.solved
  locals n
  alias p=r0x=r1
  . p=puzzlen=(MAP.W*MAP.H)
  loop n, (u32x=*p++
    if x<>NORMALreturn 0end
  endl
endf 1

function draw.puzzle
  locals xy
  . y=0
  while y<8x=0
    while x<8
      . r0=xr0*TILE.Wr0+MAP.X
      . r1=yr1*TILE.Hr1+MAP.Y
      draw.piece xyr0r1
      . 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.xselect.y
        . r++
        set.piece.rotate \
         select.xselect.yr
        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: 15302
Location: Bigweld Industries

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: 6676
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: 15302
Location: Bigweld Industries

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


Powered by phpBB © 2001-2005 phpBB Group.

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2016, Tomasz Grysztar.