flat assembler
Message board for the users of flat assembler. Index > Programming Language Design > Pointer Arithmetic: *EDI++=*ESI--
Author
 Thread  codestar

Joined: 25 Dec 2014
Posts: 254
codestar
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
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    ```
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='+'
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='+'
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]
0FB61F        MOVZX  EBX,BYTE PTR [EDI]
8819          MOV    BYTE PTR [ECX],BL
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

Last edited by codestar on 12 Jun 2015, 16:55; edited 1 time in total 31 May 2015, 09:58  revolution When all else fails, read the source Joined: 24 Aug 2004 Posts: 16903 Location: In your JS exploiting you and your system revolution Can I ask why you chose the asterisk (*) instead of the more usual assembly style square brackets ([])? [edi++] = [esi++] 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? 01 Jun 2015, 01:41
codestar

Joined: 25 Dec 2014
Posts: 254
codestar
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

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    ``` 01 Jun 2015, 02:57  revolution When all else fails, read the source Joined: 24 Aug 2004 Posts: 16903 Location: In your JS exploiting you and your system revolution 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? 01 Jun 2015, 09:20
 Tomasz Grysztar Assembly Artist Joined: 16 Jun 2003 Posts: 7496 Location: Kraków, Poland Tomasz Grysztar 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. 01 Jun 2015, 14:09
codestar

Joined: 25 Dec 2014
Posts: 254
codestar
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 01 Jun 2015, 18:30  revolution When all else fails, read the source Joined: 24 Aug 2004 Posts: 16903 Location: In your JS exploiting you and your system revolution 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. 01 Jun 2015, 22:18
codestar

Joined: 25 Dec 2014
Posts: 254
codestar
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). 02 Jun 2015, 01:46  Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First  Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsCompiler InternalsIDE DevelopmentOS ConstructionNon-x86 architecturesHigh Level LanguagesProgramming Language DesignProjects and IdeasExamples and Tutorials Other----------------FeedbackHeapTest Area

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