Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

x86 Assembly - Clear Console Text Screen?

Options
  • 22-02-2007 1:54pm
    #1
    Registered Users Posts: 9,579 ✭✭✭


    Hi There,

    I just touching up on an assignment there for college.
    It is a 386 console program that has a menu system.
    Everything works great but the output could be improved by clearing the screen eachtime the menu loads back again.
    Is there any equivilent to the 'cls' command in dos in x86.
    Come across a lot of the internet but none seem to want to work.
    It will be running on XP. Thought you could access the video memory and clear it but i'm finding it hard to get any information on the net.

    Hopefully someone with bit of experience could help.

    By way i'm using Masm 6.1 for assembling and linking.

    Cheers.


Comments

  • Closed Accounts Posts: 1,567 ✭✭✭Martyr


    to keep it simple, use system() from msvcrt.dll

    [PHP]invoke system,CStr("cls")[/PHP]

    you would prototype it in file called msvcrt.inc

    [PHP]system proto c :dword[/PHP]

    to get the library created, use polib by pelle
    i know link.exe can do this also, and masm32 by hutch has inc2l.exe but polib is better (just in future)

    pelles executables and help

    there are also excellent include files by Japheth

    i wouldn't use masm32 anymore, because its very badly maintained, but its good for beginner.
    a combination of japheths win32inc files and vc++6 processor pack from microsofts website make writing assembly programs for windows alot easier than some might think.


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    Interesting. Thank you very much :)

    I'll look into that. Well you know with college they want basic code with no help from other librarys! Anyways i'll look into that site and start messing around with it myself.

    Cheers.


  • Registered Users Posts: 695 ✭✭✭DaSilva


    As far as I can remeber, you can use the set cursor position function to clear the screen, by setting it too the first column, row and page.
    xor   dx,dx        ;dh,dl contain row column, forget which is which
    xor   bh,bh        ;0 = page 1
    mov   ah,2h
    int   10h
    


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    xor   dx,dx        ;dh,dl contain row column, forget which is which
    xor   bh,bh        ;0 = page 1
    mov   ah,2h
    int   10h
    

    Noticed and tried this before but seems to crash the program. Perhaps that is used outside Windows protected environment I amn't sure.

    Wish i could use something as simple as that but doesn't want to work.

    Any ideas why it might be crashing.


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    Just looking at the Kernel32 API procedures there in a reference PDF. Some nice handy stuff in there but seem to be unable to run some of them.

    I can do a sleep no bother:
    Sleep PROTO NEAR32 stdcall, dwMilliseconds:DWORD
    
    and i can run it by:
    Invoke Sleep,3000[code] to pause program for 3 seconds.
    
    Now this is fine as the argument for Sleep is a DWORD.
    
    [quote]Sleep: procedure
    (
    dwMilliseconds: dword
    );
    stdcall;
    returns( "eax" );
    external( "__imp__Sleep@4" );[/quote]
    
    But I am having a go at others now, for example the setConsoleTitle.
    
    [quote]SetConsoleTitle: procedure
    (
    lpConsoleTitle: string
    Win32 API Reference
    Page 431
    );
    stdcall;
    returns( "eax" );
    external( "__imp__SetConsoleTitleA@4" );[/quote]
    
    Now this expects a String but how do I define this in my Assembly program. I tried doing
    [code]SetConsoleTitle PROTO NEAR32 stdcall, lpConsoleTitle:PTR BYTE
    
    and calling it using
    Invoke SetConsoleTitle, ADDR titleStr
    
    where titleStr is a defined db in the data section as titleStr db "Title",0

    Assembles fine but wont like. It is complaining of:
    Error LNK2001: unresolved external symbol _SetConsoleTitle@4

    Any ideas what the problem might be? Bit new to this assembly stuff.
    I know its not exactly what my first post was kinda drifted to this now.

    Cheers.


  • Advertisement
  • Moderators, Recreation & Hobbies Moderators, Science, Health & Environment Moderators, Technology & Internet Moderators Posts: 91,693 Mod ✭✭✭✭Capt'n Midnight


    since the console screen is so small you could just fill it with spaces, bypassing the BIOS
    not neat or elegant though
    http://burks.brighton.ac.uk/burks/language/asm/asmtut/asm8.htm

    Listing 15: DIRECTWR.ASM
    ; write a string direct to video memory
    [php].model small
    .stack
    .code

    mov ax,@data
    mov ds,ax

    mov ax,0B800h ; segment of video buffer
    mov es,ax ; put this into es
    mov ah,3 ; attribute - cyan
    mov cx,17 ; length of string to print
    mov si,OFFSET Text ; DX:SI points to string
    xor di,di

    Wr_Char:

    lodsb ; put next character into al
    mov es:[di],al ; output character to video memory
    inc di ; move along to next column
    mov es:[di],ah ; output attribute to video memory
    inc di

    loop Wr_Char ; loop until done

    mov ax,4C00h ; return to DOS
    int 21h[/php]

    Another not neat solution - page down 26 lines and restore cursor posititon

    you could also change the video mode / page
    http://www.cs.uregina.ca/Links/class-info/250/f06/lab9/index.html

    int 10 , Ah 6 ?
    it's in the Peter Norton book ( hidden upstairs somewhere )


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    Excellent stuff Paul. I'll have a look into all that now soon.
    Thanks for that.


  • Closed Accounts Posts: 1,567 ✭✭✭Martyr


    Noticed and tried this before but seems to crash the program. Perhaps that is used outside Windows protected environment I amn't sure.

    Wish i could use something as simple as that but doesn't want to work.

    Any ideas why it might be crashing.

    if you are running 386 console program using flat model, (running in protected mode), then you cannot access the video hardware using 16-bit code.(perhaps under win9x, maybe)
    Under MS-DOS the writing to video memory buffer code would work fine, or MS-DOS emulator, like NTVDM

    from what i can see, Webmonkey.you want 32-bit console mode program, so you have to use 32-bit Windows API, not 16-bit MS-DOS code.

    here is a list of console functions

    Here is code examples on MSDN to clear screen using console functions

    here is example.

    [PHP]; ml /coff /Cp /c clear.asm
    ; link /subsystem:console clear.obj kernel32.lib
    ;
    ; using win32 include headers by Japheth - http://www.japheth.de/
    ;
    ; the kernel32.lib can be found in platform SDK or lib
    ; directory of visual studio..etc
    ; ..or you could generate it with polib by pelle
    ;
    ; polib /out:kernel32.lib %SYSTEMROOT%\\system32\\kernel32.dll
    ;
    .386
    .model flat,stdcall

    WIN32_LEAN_AND_MEAN equ 1

    include <windows.inc>

    ; Cls prototype
    Cls PROTO :HANDLE

    .data
    hStdOut DWORD ?

    .code

    start:
    invoke GetStdHandle,STD_OUTPUT_HANDLE
    mov [hStdOut],eax

    invoke Cls,[hStdOut]
    invoke ExitProcess,0

    Cls PROC USES esi ebx edi hConsole:HANDLE

    LOCAL coordScreen :COORD
    LOCAL cCharsWritten :DWORD
    LOCAL csbi :CONSOLE_SCREEN_BUFFER_INFO
    LOCAL dwConSize :DWORD

    mov [coordScreen.X], 0
    mov [coordScreen.Y], 0

    invoke GetConsoleScreenBufferInfo,[hConsole],addr csbi

    .if eax ; if eax is non-zero

    mov eax,dword ptr[csbi.dwSize.X]
    mov ecx,dword ptr[csbi.dwSize.Y]
    mul ecx ; calculate size of console
    mov [dwConSize],eax

    ; fill the entire screen with spaces

    invoke FillConsoleOutputCharacter,
    [hConsole],VK_SPACE,[dwConSize],
    coordScreen,addr cCharsWritten

    .endif
    ret
    Cls ENDP

    end start[/PHP]

    and using system() from msvcrt.dll

    [PHP]; ml /coff /Cp /c cls2.asm
    ; link /subsystem:console cls2.obj msvcrt.lib
    ;
    ; polib /out:msvcrt.lib %SYSTEMROOT%\\system32\\msvcrt.dll

    .386
    .model flat,stdcall

    system proto c :dword
    exit proto c :dword

    .data

    szCls db 'cls',0

    .code

    start:
    invoke system,addr szCls
    invoke exit,0

    end start[/PHP]

    ..if you wanted to use text on same line, you could use a macro

    [php]
    CStr macro pszText:REQ ; macro by Japheth
    local szText
    .const
    szText db pszText,0
    .code
    exitm <offset szText>
    endm
    [/php]

    then on one line
    [php]
    invoke system,CStr(<'cls'>)
    [/php]


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    You're right I using Flat Model. Thanks for that, at least i know now why it was crashing.

    That code looks good cheers. Even though i've handed up the assignment now - It looked ok at the end even without the screen clear.

    Thanks for that code though, definetely use it in future!


Advertisement