Help on VGA and putpixel intel x86 asm AT&T syntax
I want to draw a colored line in asm. I have to use AT&T syntax, on an x86 intel linux unit. I got pretty far already, but I'd like to know how to enter VGA-mode, or Mode-X, and how to put a pixel on the screen. Is there a function for that in a standard C library (like printf)?
Thanks a lot for your help. :)
.bss # Declaring uninitialized variables
.data # Declaring initialized variables
.text # Actual assembly code and constants
intro: .asciz "Draw a line in VGA\n\n"
clr: .asciz "Give a color \n"
optns: .asciz "red (1), blue (2), white (3)\n"
res .asciz "%d"
ent: .asciz "\n"
.global main # Tell kernel where to start (visible from outside)
main: pushl %ebp # Push base pointer movl %esp, %ebp # Initialize base pointer pushl $intro # Push the string address call printf # Call the printf routine from C library addl $8, %esp
pushl $clr # push color question on the stack
call printf # Print it
subl $4, %esp # Reserve stack space for variable
leal -4(%ebp), %eax # Load address of stack var in eax
pushl %eax # Push second argument of scanf
pushl $rets # Push first argument of scanf
call scanf # Call scanf
movl 4(%ebp), %ecx # mov the result in ecx
cmpl $1, %ecx
je red
cmpl $2, %ecx
je blue
jne white
red: #... still working on this
movl 0013h, %eax # enter 320x200x256 mode
int 10h # IS THIS CORRECT?
movl $0, %ebx # set X to 0
movl $0, %ecx # set Y to 0
call draw # Call line routine
movl 0003h, %eax # IS THIS CORRECT?
int 10h # return to text mode
movl $0, (%esp) # Make esp 0, indicating succesful termination
call exit # Exit the program
draw:
call putpixel # pushl %ebp # Push the base pointer # movl %esp, %ebp # Initialize base pointer inc %ebx 开发者_Go百科 # increment X inc %ecx # increment Y cmpl $200, %ecx # check if Y => 200 jge end # if Y=> 200, jump to end jmp draw # loopputpxl: #has to put a pixel at (%ebx, %ecx) and return to draw # should use the color from the main routine
end: movl %ebp, %esp # Remove local variables popl %ebp # Remove base pointer ret # return to main routine
Best thing you could do would be to use a higher-level library, like SDL or Allegro. This way, your program will work on top of X11 and on non-VGA framebuffers (e.g: displays on embedded ARM-based devices).
Svgalib allowed to program for VGA and so-called SVGA graphics cards. Its development stopped years ago.
There are two ways to access VGA hardware:
- Using registers
- Using the VGA BIOS: this is the one you've tried. VGA BIOSes are written to run in real mode. To invoke them from protected mode, you would need to switch to vm86 mode. which is what LRMI (Linux Real Mode Interface, the opposite of DPMI) did.
You are not allowed to do direct video (graphic mode) output in linux (protected OS). it was possible only in a dos (real-mode OS).
You can use framebuffer device or SDL, or libX11. But there is no reason why to do work with high-level libraries from the asm.
Int 10 is not allowed in linux directly (in user mode; the kernel must do low-level accesses).
e.g. this is 5 year old exact the same discussion http://www.gamedev.net/topic/368196-linux-assembler-int-10h/
精彩评论