ASM help

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Silenger

ASM help

Post by Silenger »

I am using Free Pascal as compiler.
So i wrote a Print Pascal String function...

Because pascal is buildup like this:
db Length, Text, db 0
and when using dynamic strings the compiler does this:
db 2, 'Hi000 .... to 255 ', db 0

So the only chose is to write a print function to deal with this.

procedure WriteStr(XPos, YPos, Attribute: Byte; Str: String); assembler; [public, alias: 'SR_WRITESTR'];
asm
???XOR???EDX, EDX?????????{Clear}

???MOV???DX, XPos?????????{XPos}
???MOV???CX, YPos?????????{YPos}
???MOV???ESI, Str?????????{Str pointer}

???SHL???CX, 40?????????{YPos * 80}
???ADD???DX, CX?????????{XPos + (YPos * 80)}
???SHL???DX, 1????????????{DX * 2, because of the attribute}

???ADD???EDX, $B8000?????????{Screen pointer}
???MOV???EDI, EDX?????????{Destination pointer}
???XOR???EAX, EAX?????????{Clear}
???LODSB???????????????{Read string length}
???MOV???ECX, EAX?????????{Set length in counter}

???MOV???AH, Attribute??????{Attribute / Color}

???@PrintChar:
??????LODSB????????????{Put char in AL}
??????STOSW????????????{Write AX to Mem}
???LOOP???@PrintChar?????????{If ECX != 0, write next}
end;

The string is printed on the screen but not at the right place!

SHL???CX, 40 <- PROBLEM

Why is this rong or doesn't work ??? , one shift to left = *2 right?

EDIT: Can it be because i use the ECX (CX) register?
Jamethiel

Re:ASM help

Post by Jamethiel »

It's wrong because:

Shift counts on the x86 are taken mod 32 (this has bitten me before, usually when I need them mod 64).
So you have SHL CX, 8 (40 - 32 = 8).

A shift by 8 is equivelant to multiplying by 256. (2^8).
You are therefore throwing your Y position of by a whole bunch of lot.

So, let's try this again:

80 decimal is 64 + 16 is $50 hex.

Assuming you don't want to use IMUL or anything, the simplest way is:

SHL CX, 4 {YPos * 16}
ADD DX, CX {XPos + YPos * 16}
SHL CX, 2 {YPos * 64}
ADD DX, CX {XPos + YPos * 16 + YPos * 64 = XPos + YPos * 80}

Hope this helps and wasn't too unclear of an explanation.

--Jamethiel

SHL DX, 1
Silenger

Re:ASM help

Post by Silenger »

Thx Jamethiel!

I better read that bit wise tutorial not so fast ;D

( XPos + ( YPos * 16 ) ) + ( ( YPos * 16 ) * 4 ) :D

So:

procedure WriteStr(XPos, YPos, Attribute: Byte; Str: String); assembler; [public, alias: 'SR_WRITESTR'];
asm
   XOR   EDX, EDX         {Clear}

   MOV   DX, XPos         {XPos}
   MOV   CX, YPos         {YPos}
   MOV   ESI, Str         {Str pointer}

   SHL   CX, 4            {YPos * 16}
   ADD   DX, CX         {XPos + (YPos * 16)}
   SHL   CX, 2            {(YPos * 16) * 4}
   ADD   DX, CX         {XPos + (YPos * 80)}
   SHL   DX, 1            {DX * 2}

   ADD   EDX, $B8000         {Screen pointer}
   MOV   EDI, EDX         {Destination pointer}
   XOR   EAX, EAX         {Clear}
   LODSB               {Read string length}
   MOV   ECX, EAX         {Set length in counter}

   MOV   AH, Attribute      {Attribute / Color}

   @PrintChar:
      LODSB            {Put char in AL}
      STOSW            {Write AX to Mem}
   LOOP   @PrintChar         {If ECX != 0, write next}
end;
Post Reply