Search code examples
assemblyx86masmi386

How to "draw" a letter in assembly(VGA mode, MASM, .386)?


I'm doing a university project and I'm really bad at assembly, so I ask for your help.
"In the VGA mode (320x200 pixels -256 colors) it should been "drawing" 2 letters(D and Q) centered on vertical with height at least 100 pixels. The height would be configurable and stored into an variable and the should not run if the height it's under 100 pixels. The width and their position it's at choice."
I have done some research and the code is my result and I know it's not exactly as my requirement and I hope you can help me.
1.For the VGA mode should i have a monitor connected through a VGA cable to actually see if my program runs and it's good?
2.It's true that DS is taking automatically the data from .DATA?
3.With the syscall it should wait until a keyboard is pressed?
We usually use at university notepad++ with masm plugin and ollydbg as debugger but I'm open as long as they do what is supposed to do. It had to be for .386.
Thanks in advance, and especially for reading this far.

.386
.model flat, stdcall
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;including msvcrt.lib, and declaring what function to import
includelib msvcrt.lib
extern exit: proc 
;declare the symbol start as public - from there execution starts
public start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;declaring data we are using
data segment
 letter1 db 'D'
 letter2 db 'Q'
 COLORTEXT    equ   7

.code

_InitializeMCGA PROC

MOV AX, 0A000h
MOV ES, AX ; ES now points to the VGA

MOV AH, 00H ; Set video mode
MOV AL, 13H ; Mode 13h
INT 10H ; We are now in 320x200x256
RET

_InitializeMCGA ENDP

start:

    ;MOV AX, @DATA
    ;MOV DS, AX ; DS now points to the data segment.
    ;those 2 instructions above are commented because I read that DS is taking automatically the data from .DATA
    ;let me know if it's wrong 

    CALL _InitializeMCGA ; ENTER MODE 13H
    MOV AH, letter1
    MOV ES, AX
    MOV BP, OFFSET COLORTEXT ; ES: BP POINTS TO THE TEXT
    MOV AH, 13H ; WRITE THE STRING
    MOV AL, 01H; ATTRIBUTE IN BL, MOVE CURSOR TO THAT POSITION
    XOR BH,BH ; VIDEO PAGE = 0
    MOV BL, COLORTEXT ;colour (7=white as far as I know)
    MOV CX, 25 ; LENGTH OF THE STRING
    MOV DH, 50 ;ROW TO PLACE STRING
    MOV DL, 10; COLUMN TO PLACE STRING
    syscall ;wait for keyboard to be pressed

    MOV AX, 4C00H ;dos exit
    INT 21H  ; Return to DOS
    ;finish the program
end start

Solution

  • Since you're using MASM and Int21h, I presume you're targeting DOS. Should've mentioned so.

    1. VGA video mode doesn't mean you have to use the VGA cable.
    2. Depends. Usually it does.
    3. You can't use syscall in DOS. Use interrupt 16h, AH=0 to read a key.

    And for character output, I'd recommend interrupt 10h, function 9. Use function 2 to position the cursor.

    EDIT:

    First, you look up the interrupt documentation. Even Wikipedia provides some.

    Then in code, you assign values to registers according to the spec, and call the interrupt. For example, for INT 10 function 2 it would go:

    mov ah, 2h ; the function
    mov bh, 0 ; the page - assume 0
    mov dh, 1 ; row
    mov dl, 5 ; column
    int 10h
    

    Kind of like that. But there's more than one interrupt call to your requirements.

    Now, as to building and running, you'd have to ask a teacher. And you test it by building and running the executable. I'm sure they've explained to you how at some point; since there's no single right way to build assembly programs, I don't know what does your professor expect and therefore can't help much with that.