My print string function

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.
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

My print string function

Post by bubach »

Hello.
I have got a couple of cursor functions and a print_char (bl = char, bh = attrib) function.

I then wrote a print function that uses print_char.
It looks like this:

Code: Select all

; Display a asciiz message on the screen.
;       Input: ESI = Message, AL = COLOR.
;--------------------------------------------
     print:
          pusha                                       ; save all registers (just in case)
          mov     bh, al                              ; move attrib. to bh

     .DisplayChar:
          lodsb                                       ; load next character
          or      al, al                              ; test for NULL character
          jz      .Done

          cmp     al, 0x0D                            ; Check for ENTER
          je      .Enter

          cmp     al, 0x0A                            ; ignore the sec. enter char
          je      .DisplayChar

          mov     bl, al                              ; BL = char. Bh = attrib.
          call    print_char                          ; print it.
          jmp     .DisplayChar

     .Enter:
          call    getcursorxy                         ; DH = X .  DL = Y.
          mov     dh, 0x00
          inc     dl
          call    setcursorxy
          jmp     .DisplayChar

     .Done:
          popa                                        ; restore all registers.
          ret
it may be a bit messy right now, becasue i have modified it alot.
as i said, the print_char function works just fine and it does also takes care about the cursor and scrolling up.

whats worng with this d*mn code?

/ Christoffer
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
ASHLEY4

Re:My print string function

Post by ASHLEY4 »

Hi
This is mine and it works fine if it helps:

Code: Select all

 ;'''''''''''''''''''''''''''''''''''''''''''''''''''';
 ; Prints string      ; does what it say's on the box ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;  Input:                                            ;
 ;      es:esi points to asciiz string to write.      ;
 ;                                                    ;
 ; Output:                                            ;
 ;      None.                                         ;
 ;....................................................;

print_string:
   push  eax
   push  esi
aloop:
   mov   al,[esi]
   cmp   al,0                       ; 0x00 = end of string
   je    gend
   cmp   al,0x0D                       ; 0x0d = CR ( = \n )
   jne   no_cr
   call  carriage_return
   jmp   a1
no_cr:

   call  print_char
a1:   inc   esi
         jmp   aloop
gend:
        call  set_cursor_pos
   pop   esi
   pop   eax
   ret

ASHLEY4.
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:My print string function

Post by bubach »

It?s just complicated to use your function when i don?t got the same functions for print_char etc. that you use.

Anyone else? Do you need some more code?

here is my print_char function, but it works so i don?t think that?s the problem.

Code: Select all

; Print char. IN: bl = char, bh = attrib 
;----------------------------------------
print_char:     pushad ;
                push    es

      push   ebx
      call    getcursorxy

      cmp   dh,79
      jb   .snok

      cmp   dl,49
      jb   .snok

      call    getcursor

      pop   edx
      movzx   ebx,bx
      mov     [es:(ebx*2 + 0xb8000)],dx

      call   scroll_up
      call   _scroll_up.mv_curs
      jmp   .exit

.snok:          cmp     dl,50
                jnae short .1

      call   scroll_up
      call   _scroll_up.mv_curs

.1:      call    getcursor

      pop   edx
      movzx   ebx,bx
      mov     [es:(ebx*2 + 0xb8000)],dx

                call    inccursor

.exit:
      pop     es
                popad
                ret
/ Christoffer
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
ASHLEY4

Re:My print string function

Post by ASHLEY4 »

You have not said what is wrong?
What does it do when you use it?

ASHLEY4.
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:My print string function

Post by bubach »

hehe, sorry i forgot that..
i have tested it with diffrent modifications and the result is oftest that it changes to the next line and then stops.
one time nothing happend at all, one time it printed weird characters on the first (1) place on the lines under the starting cur. pos.

if i remember it right, it makes a new line but dows not print anything..

my mess. looks something like this:

string db 0x0d, 0x0a, "testing", 0x00

/ Christoffer
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
ASHLEY4

Re:My print string function

Post by ASHLEY4 »

Code: Select all

??????mov     [es:(ebx*2 + 0xb8000)],dx
To me you have the bx and dx the wrong way round?

ASHLEY4.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:My print string function

Post by Candy »

bubach wrote: here is my print_char function, but it works so i don?t think that?s the problem.

Code: Select all

      cmp   dh,79
      jb   .snok
jb == jump if below, or jump if carry (same opcode). Second minus first is going to jump for every time the values are "onscreen". You probably mean ja.

- checked in intel manual, cmp 05, 79 = carry set

You thus always jump if it's on screen. BTW, what does snok mean? Guess: iS Not OK
cmp dl,49
jb .snok
same here
push ebx
...
pop edx
This looks wrong but is correct.

Could we see getcursorxy and setcursorxy?
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:My print string function

Post by bubach »

Ok. Sure. Here it is..

edit: snok is either a ugly name of a nose or a kind of a snake.. not my function but from another swedish guy..

Code: Select all

; Get the cursor pos. OUT: DH = X   DL = Y
;------------------------------------------
getcursorxy:    push    eax
                push    ebx

??????mov???dx,3d4h
??????mov???al,0eh
??????out???dx,al
??????inc???dx
??????in???al,dx
??????mov???bh,al
??????mov???al,0fh
??????dec???dx
??????out???dx,al
??????inc???dx
??????in???al,dx
??????mov???bl,al

??????mov???dx,bx
??????mov???ax,bx
GC1:??????sub???dx,80
??????cmp???dx,ax
??????jna???GC1

                add     dx,80

                push    edx

                sub     bx,dx           ;bx = y*80

                mov     ax,bx
                mov     bl,80
                div     bl

                mov     dl,al
                pop     ebx
                mov     dh,bl

                pop     ebx
                pop     eax
                ret

Code: Select all

; Set the cursor to:  DH = X   DL = Y
;--------------------------------------
setcursorxy:    push    eax
                push    ebx
                push    edx

                movzx   bx,dl
??????mov???ax,bx
??????shl???ax,4
??????shl???bx,6
??????add???bx,ax
                movzx   ax,dh
??????add???bx,ax

setcursor_real: mov???al,0eh
??????mov???ah,bh
??????mov???dx,3d4h
??????out???dx,ax
??????inc???ax
??????mov???ah,bl
??????out???dx,ax

                pop     edx
                pop     ebx
                pop     eax
                ret
/ Christoffer
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:My print string function

Post by Candy »

bubach wrote: edit: snok is either a ugly name of a nose or a kind of a worm.. not my function but from another swedish guy..
personal opinion: people should code only in english. Makes it a lot more portable between programmers.

Code: Select all

      mov   dx,3d4h
      mov   al,0eh
      out   dx,al
      inc   dx
      in   al,dx
      mov   bh,al
      mov   al,0fh
      dec   dx
      out   dx,al
      inc   dx
      in   al,dx
      mov   bl,al
I expect this to be some code that loads the value of the current offset per byte into bx (hope you got the endianness correct, don't know the ins & outs of the CRTC).

Code: Select all

      mov   dx,bx
      mov   ax,bx
GC1:      sub   dx,80
      cmp   dx,ax
      jna   GC1

                add     dx,80
This confuses me. You put the offset into ax and dx, and then loop through a substraction of 80 from dx, comparing it with the original value it had. What ARE you trying to do? jna is not logical here... Jump if Not Above, so if dx is below ax. If it wraps around, you get it being above, so you'd then add 80 back, and end up with the lower half... really icky code.

Code: Select all

                push    edx

                sub     bx,dx           ;bx = y*80

                mov     ax,bx
                mov     bl,80
                div     bl
You have apparently put the lower half of the to be extracted value in dx, and now substract it from bx (which was also the original value of dx). This leaves bx to be the exact y * 80, and then you use div for the y-part. al ends up being the y-part and dl (and bl) are the lower or X-part.

Code: Select all

                mov     dl,al
                pop     ebx
                mov     dh,bl

                pop     ebx
                pop     eax
                ret
shuffling & restoring

You've got a bug here. bl was wrecked because you moved a 80 there. However, it's also easy to fix, because dl does hold what you wanted bl to hold. Swap the mov dh, bl with the mov dl, al and change it to mov dh, dl (or shl dx, 8).

Ok, may I? (please, don't be offended... it's just that I like making clear assembly programs, and always find such hard targets for my own assembly that they end up being not clear)

Code: Select all

    xor dx, dx

GC1:
    sub bx, 80
    inc dl
    cmp bx, 80
    ja GC1

    mov dh, bl
this should do the same as the parts I mentioned being icky (imho). Also fixes the bug & shortens your code considerably.

Code: Select all

                movzx   bx,dl
      mov   ax,bx
      shl   ax,4
      shl   bx,6
      add   bx,ax
                movzx   ax,dh
      add   bx,ax
If you could be able to do this with SIB, it'd be so clear...

Anyway, 16*y + 64*y + x = offset. That's true.


edit - I am such a dopefish. Wrong jump.
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:My print string function

Post by bubach »

personal opinion: people should code only in english. Makes it a lot more portable between programmers.
i agree.. but as i said, it?s not my code..
i had my own setcursorxy and printchar (that i was quite prode of), but when i couldn?t find out how to "getcursorxy" i throw it all away for this code that was in a swedish gpl:ed os zip.. ( becasue it had it all+it lokked nicer then my functions! :-( )

becasue i could?nt get his print function to work i started on this...
the functions provided (except print) is?nt mine, but afaik they works fine. the print_char functions use the set/get cur. xy and that works... it may not be that great code to the eye, but i am 99% sure it works.. the only function i hav?nt tested (but it uses) is getcursorxy...

anyway, do you think that the things u pointed out will solve it? i will look it throw and be back tomorrow.. :-)
thanks!

/ Christoffer
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:My print string function

Post by Candy »

bubach wrote:
personal opinion: people should code only in english. Makes it a lot more portable between programmers.
i agree.. but as i said, it?s not my code..
That's no excuse for finding it in your code base.
anyway, do you think that the things u pointed out will solve it? i will look it throw and be back tomorrow.. :-)
thanks!
Honest answer? I hope so, but doubt it. Somehow I was expecting esi to be wrecked somewhere, but it seems to be kept intact during all the calls. Also, none of the segments are adjusted, so esi keeps pointing to the same place. The only thing I could possibly find wrong is the place calculation, or something similar. That points to this.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:My print string function

Post by Candy »

New view on the printchar function:

Code: Select all

; Print char. IN: bl = char, bh = attrib 
;----------------------------------------
print_char:     pushad ;
                push    es

      push   ebx
      call    getcursorxy
dh = 80 (because of bug), dl is y

Code: Select all

      cmp   dh,79
      jb   .snok

      cmp   dl,49
      jb   .snok
first jump never taken, second always (if on screen).

Code: Select all

      call    getcursor

      pop   edx
      movzx   ebx,bx
      mov     [es:(ebx*2 + 0xb8000)],dx

      call   scroll_up
      call   _scroll_up.mv_curs
      jmp   .exit
that's dead code by my definition

Code: Select all

.snok:          cmp     dl,50
                jnae short .1
now, if dl == 49, it jumps. Not relevant here

Code: Select all

      call   scroll_up
      call   _scroll_up.mv_curs
say what? we didn't get those functions from you :). How do these scroll up?

Code: Select all

                call    inccursor
again, what's this? How does it function? In particular, does it use getcursorxy?

- sorry bout second post of mine, thought it would exceed the limit
ASHLEY4

Re:My print string function

Post by ASHLEY4 »

Code: Select all

??????mov     [es:(ebx*2 + 0xb8000)],dx
I may be wrong, but this is b******t ,you take the char + attrib x them by 2 + 0xb8000 + es and then you put the char + attrib at that address, and think that it will work :D.

You push ebx with the char and attrib
when you call proc's you save these seting,
then you pop edx so it as the char + attrib in.

ASHLEY4.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:My print string function

Post by Candy »

ASHLEY4 wrote:

Code: Select all

      mov     [es:(ebx*2 + 0xb8000)],dx
I may be wrong, but this is b******t ,you take the char + attrib x them by 2 + 0xb8000 + es and then you put the char + attrib at that address, and think that it will work :D.

You push ebx with the char and attrib
when you call proc's you save these seting,
then you pop edx so it as the char + attrib in.

ASHLEY4.

Code: Select all

      call    getcursor

      pop  edx
      movzx  ebx,bx
      mov    [es:(ebx*2 + 0xb8000)],dx
you load the cursor offset in bx (getcursor), pop the char + attr in dx, zero-extend the offset to ebx (for the SIB addressing) and then move the char + attr to the offset + 0xb8000. What is wrong?

Note that the cursor offset is per word.
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:My print string function

Post by Neo »

dont want to sound patronising but is there any reason why ur doing this in ASM. It would be a few easy lines in C (IMHO)
Only Human
Post Reply