Machine gunning the video

[b][red]This message was edited by shaolin007 at 2003-10-29 12:21:28[/red][/b][hr]
I'm still learning assembly and I'm trying to practice the stos instruction. First off here is my code...

[code]


BITS 16
ORG 0x0100


SEGMENT .text ;Main code segment


mov ax, 0b800h
mov es, ax
xor ax,ax
xor di,di
mov cx, 3999
call machine_gun
mov ah, 08h
int 21h
call done

machine_gun:

mov al, 'a'
mov [es:di], al
dec cx
inc di
rep stosb
ret

done:
mov ax, 4c00h
int 21h
ret

[/code]

1st question is, could I use the stosw instruction to do this and how? All I could do with it was write an 'a' then the rest of the screen was yellow. When I use the stosb instruction it works out fine. 2nd, I thought the default background attribute would be black, but it's yellow, how do you change that directly? 3rd, why do I have to double the cx counter since 80x25=2000? Thanks for your help.


Comments

  • the text-segment holds 2(!) bytes for each character,one containing the ascii-code of the char and one for its attributes.the attribute-byte contains 4 bits for color,3 for background and bit7 is the blinking-bit.

    so you use something like that:

    mov al,'A'
    mov al,07h
    stosw ; stos a grey-'A' on black ground
  • [b][red]This message was edited by Bitdog at 2003-10-29 14:8:31[/red][/b][hr]
    A simple version
    [code]
    BITS 16
    ORG 0x0100 ;Nasm .COM file
    mov ax,0b800h
    mov es,ax ;FAST CLEAR SCREEN CODE
    xor di,di ;ES:DI = destination
    MOV AH,7 ;color dim white on black, 8=grey
    MOV AL,32 ;32=space character
    mov cx,2000 ;count
    REPZ STOSW ;quick do the work
    mov ah,08h ;pause, get key with out echo
    int 21h
    mov ax,4c00h ;correct exit code
    int 21h
    [/code]


    Your code I commented/butchered
    [code]
    BITS 16
    ORG 0x0100 ;this looks NASMish, so the next .COM line isn't needed
    ; SEGMENT .text ;Main code segment
    mov ax,0b800h
    mov es,ax
    xor ax,ax ;char 0 looks like a space,
    ;& attribute 0 is black on black
    ;so you can never write anything on the screen you can see
    ;except for the last byte cause you used 3999 instead of 4000?
    xor di,di
    mov cx,3999 ;4000 is what I use
    call machine_gun ;if your code only calls a proc once, put it
    ;where it's called, but just a REPZ STOSW is all that's required
    mov ah, 08h
    int 21h
    call done ; should be JMP DONE, CALL pushes the return address
    JMP DONE

    machine_gun:
    mov al, 'a' ;you don't have AH=color
    mov BYTE [es:di], al ;BYTE size was not stated, (it worked though?)
    dec cx ;now CX=3998 two bytes short of a full screen
    inc di ; I don't know why you DEC DI,
    ; INC DI ; would be proper code in a loop;
    rep stosb ; you are writing the character to the attribute byte also
    ;I don't know why the mov BYTE then the stosb, just testing stuff I guess?
    ret
    :
    DONE:
    mov ax, 4c00h ;correct exit code
    int 21h
    ; ret ;this never gets run, IP never gets here.

    ;A .COM will quit with a RET statement but your AX=4c00h INT 21h
    ;is the correct exit/quit program code.
    [/code]
    :
    : 1st question is, could I use the stosw instruction to do this and how?
    REPZ STOSW ; AH=color, AL=character, CX=2000 count

    : All I could do with it was write an 'a' then the rest of the screen was yellow.
    You wrote the character to the attribute byte also

    : When I use the stosb instruction it works out fine.
    Use REPZ STOSW or in a loop STOSB & INC DI to skip the attribute byte

    : I thought the default background attribute would be black, but it's yellow, how do you change that directly?
    stos Word would have done that, but black writeing on a black back ground can't be seen.

    : Why do I have to double the cx counter since 80x25=2000?
    2000 characters
    +2000 attributes
    =4000 bytes total

    but if you write two bytes at a time AH=color AL=char REPZ STOSW then CX=2000
    REPZ = REPeat untill cx = Zero

    I hope that helps some how

    Bitdog

  • Thanks for the help, and the suggestions/modifications to my code. Does PUSH ES save the current graphics mode or something? You mentioned it in your version being a good practice? Anyways, I modified my code to look similiar to what you suggested and I would like you to take a look again, and see if I can improve it further. Thanks again.

    [code]

    BITS 16 ;Set code generation to 16 bit mode
    ORG 0x0100 ;Set code start address to 0100h

    mov ax, 0b800h
    mov es, ax
    xor ax,ax
    xor di,di
    mov cx, 2000

    mov al, 'a'
    mov ah, 07h
    mov [es:di], ax
    dec cx
    inc di
    inc di
    repz stosw
    mov ah, 08h
    int 21h
    mov ax, 4c00h
    int 21h

    [/code]

    Have a good weekend!





  • [b][red]This message was edited by Bitdog at 2003-10-30 17:9:13[/red][/b][hr]
    :take a look again, and see if I can improve it further.
    [code]

    BITS 16 ;Set code generation to 16 bit mode
    ORG 0x0100 ;Set code start address to 0100h
    mov ax, 0b800h
    mov es, ax
    ; xor ax,ax ;not needed
    xor di,di
    mov cx, 2000

    mov al, 'a'
    mov ah, 07h
    ; mov [es:di], ax ;not needed loop part
    ; dec cx
    ; inc di
    ; inc di
    repz stosw ;this does all the work for you
    mov ah, 08h
    int 21h
    mov ax, 4c00h
    int 21h
    [/code]

    The un_needed part is for a loop, but the REPZ STOSW is a loop proc in an instruction that's as quick as anything.
    You're writing an 'a' 2000 times which seems funny, but it's a test program I take it. Changeing the 'a' to 32=space=' ' would clear the screen and thats usefull code.
    If you wanted to do the loop thing, here's a couple stuffs
    [code]
    ;ES:DI assume is already pointed to the Vmem destination
    MOV CX,2000 ;loop counter
    MOV AL,' ' ;character=space 32
    MOV AH,7 ;color, 4=red
    ZZTOP:
    MOV WORD [ES:DI],AX ; stow the char & attribute=color
    INC DI
    INC DI
    DEC CX ;this sets the ZF=Zero Flag when CX=0
    JNZ ZZTOP ;jump short if CX not equil 0

    ;or if you want to write a string, try this,
    MESSAGE DB "Howdy Wurld !",0
    ;ES:DI destination already = Vseg:offset
    ; MOV CX,2000 ;(edited OOPS, CX isn't needed)
    MOV AH,4 ;color
    MOV SI,MESSAGE ; address of message source in DS:SI now
    ZZTOP:
    LODSB ;=get a message byte in AL from [DS:SI] & INC SI
    OR AL,AL ;check for 0=nul string end
    JZ DONE
    STOSW ;write both the AL=char & AH=color
    JMP SHORT ZZTOP
    DONE:
    [/code]

    PS, your codeing looked real clean, congrats.........
    Bitdog



Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories