5

我想在 asm 中画一条彩色线。我必须在 x86 intel linux 单元上使用 AT&T 语法。我已经走得很远了,但我想知道如何进入 VGA 模式或 Mode-X,以及如何在屏幕上放置一个像素。标准 C 库(如 printf)中是否有此功能?

非常感谢你的帮助。:)

.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 # increment X inc %ecx # increment Y cmpl $200, %ecx # check if Y => 200 jge end # if Y=> 200, jump to end jmp draw # loop

putpxl: #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

4

2 回答 2

2

您不允许在 linux(受保护的操作系统)中进行直接视频(图形模式)输出。只有在dos(实模式操作系统)中才有可能。

您可以使用帧缓冲设备或 SDL,或 libX11。但是没有理由使用 asm 中的高级库。

linux 中不允许直接使用 int 10(在用户模式下;内核必须进行低级访问)。

例如,这是 5 岁的完全相同的讨论http://www.gamedev.net/topic/368196-linux-assembler-int-10h/

于 2011-07-29T14:45:26.553 回答
2

您可以做的最好的事情是使用更高级别的库,如 SDL 或 Allegro。这样,您的程序将在 X11 和非 VGA 帧缓冲区上运行(例如:在基于 ARM 的嵌入式设备上显示)。

Svgalib 允许为 VGA 和所谓的 SVGA 图形卡编程。它的发展在几年前就停止了。

有两种方法可以访问 VGA 硬件:

  • 使用寄存器
  • 使用 VGA BIOS:这是您尝试过的。VGA BIOS 被编写为在实模式下运行。要从保护模式调用它们,您需要切换到 vm86 模式。这就是 LRMI(Linux 实模式接口,与 DPMI 相反)所做的。
于 2011-07-29T15:17:43.810 回答