Re: Formatting in assembly



Betov wrote:
"James Daughtry" <mordock32@xxxxxxxxxxx> écrivait

atoi:
mov esi,D$esp+4 | mov ecx,D$esp+8
mov eax,0

L0: jecxz L1>
; Convert from ASCII, add to LSD
movzx ebx,B$esi | sub ebx,'0'
mov edx,10 | mul edx | add eax,ebx

inc esi | dec ecx
jmp L0<
L1:
ret

----------------------------------------------------
Proc AsciiToEax:
Arguments @Buffer, @NumberOfChars
Uses esi, ebx, ecx, edx

mov esi D@Buffer, ecx D@NumberOfChars
mov eax 0, ebx 0, edx 10

While ecx > 0
mul edx
mov bl B$esi | sub bl '0' | add eax ebx
inc esi | dec ecx
End_While
EndP
----------------------------------------------------

You are joking again. That looks like a random distribution of characters
on the screen. And if you read a single line, you have to move your eyes
from left to right to left to right ....

mov bl B$esi | sub bl '0' | add eax ebx
^ ^ ^ ^ ^ ^ ^ ^ ^
1 3 2 4 6 5 7 9 8

Because you need a disassembler to understand the above code, I
downloaded and illegal used RosAsm (I already deleted it so I hope
that's not a problem; have I also to remove some registry entries?).
But wasn't able to assemble the above code so I searched one of the
demos for the definition of the "While" macro (RosAsm doesn't even
generate a listing so you really have to use a disassembler to look
at the generated code).

AsciiToEax:
00000000: 3e 8b 74 24 04 move.l 4.b(r7),r5 ; pointer to buffer
00000005: 3e 8b 4c 24 08 move.l 8.b(r7),r2 ; number of digits
0000000a: b8 00000000 move.l #0,r0
0000000f: bb 00000000 move.l #0,r3
00000014: ba 0000000a move.l #10,r1

00000019: 81 f9 00000000 _10: cmp.l #0,r2
0000001f: 76 0d bls.b _20
00000021: f7 e2 mulu.l r1,r0,r1|r0
00000023: 8a 1e move.b (r5),r3
00000025: 80 eb 30 sub.b #'0',r3
00000028: 01 d8 add.l r3,r0
0000002a: 46 inc.l r5
0000002b: 49 dec.l r2
0000002c: eb eb br.b _10
0000002e: c3 _20: rts.l

Some comments:

If the number of digits is 0, you don't need to initializes r5,r3,r1
"eor.l r0,r0" is 3 bytes shorter than a "move.l #0,r0"
"lea.l 10.b(r0),r1" is two bytes shorter than a "move.l #10,r1"

If the number doesn't fit into 32 bit, then your "10" in edx
is destroyed by the multiplication, better us a different register.

You have two branch instruction within the loop, only one is needed.


Here an "assembler version" of the code:


0000002f: 31 c0 atoi: eor.l r0,r0
00000031: 3e 8b 4c 24 08 move.l 8.b(r7),r2 ; number of digits
00000036: 09 c9 or.l r2,r2
00000038: 74 15 beq.b _20
0000003a: 3e 8b 74 24 04 move.l 4.b(r7),r5 ; pointer to buffer
0000003f: 31 db eor.l r3,r3

00000041: 6b c0 0a _10: mulsq.l #10,r0,r0
00000044: 8a 1e move.b (r5),r3
00000046: 80 eb 30 sub.b #'0',r3
00000049: 01 d8 add.l r3,r0
0000004b: 46 inc.l r5
0000004c: 49 dec.l r2
0000004d: 75 f2 bne.b _10
0000004f: c3 _20: rts.l
.



Relevant Pages