📄 编译xwindows下的汇编代码 .txt
字号:
编译Xwindows下的汇编代码
作者:梅 松 于2007-9-16上传
--------------------------------------------------------------------------------
作者:梅 松 湖北省郧县公安局 442500
Xwindows?写错了吧,多了个X?
没错,Xwindows是linux的系统图形界面,而且Xwindows程序也能用汇编写代码!
不过因为masm不支持跨平台,所以我们选择支持跨平台的编译工具NASM。
一般介绍NASM的时候先介绍NASM语法,弄的初涉及此领域的爱好者一头雾水,积极性备受打击。这里先我们教大家编译出第一个linux下的图形hello world!程序,以提高大家学习的兴趣 :)。
首先需要您的linux系统中安装有GCC和NASM包,没有的话请安装它们(安装方法网上有教程的)。其次需要您有编辑NASM代码的编辑器(linux下的编辑器多如牛毛,随便一个都行的)。另外需要您有极大的热情,呵呵。
我们把下面这段代码粘贴到编辑器里,以2.asm存盘。
; 2.asm
; assemble:
; nasm -f elf -o 2.o 2.asm
;
; link:
; gcc -s -nostartfiles -o 2.bin 2.o -L/usr/X11R6/lib -lX11
;
; run:
; ./2.bin
;
; handy constants
;
NULL equ 0
; make entry-point "global" so linker can see it
;
global _start
; Xlib API functions
; (Xlib is a C library for programming X)
;
; All API are C functions and follow the usual C
; conventions...Xlib is meant for C coding, really,
; but, of course, ASM can access anything it likes
; so I'm "borrowing" the C library to make the
; programming shorter and easier :)
;
extern XOpenDisplay
extern XDisplayName
extern XCloseDisplay
extern XDefaultRootWindow
extern XCreateSimpleWindow
extern XDestroyWindow
extern XSelectInput
extern XMapWindow
extern XNextEvent
; constants to do with the "events"
; but this program is very boring and only
; looks for the "KeyPress" event that I'm
; only bothering to define the constants
; for that and ignoring all the others...
;
%define KeyPressMask 1
%define KeyPress 2
; data section
;
section .data
StringOpenFailed db 0Ah, "Error: Cannot open display!"
Display dd 0 ; Display "handle" (actually a pointer)
Window dd 0 ; Window "handle"
event times 24 dd 0 ; "event" structure (unlike Windows,
; every event is actually has
; variable-length data associated with
; it...it's simply convenience, though,
; to make one structure big enough for
; any message and to "re-use" it...a
; touch of "laziness" there for easy
; implementation ;)
; code section
;
section .text
_start:
; Connect to X
;
; The parameter is to specify which X to connect to,
; as X is capable of working across networks, as well
; as locally...so, for example, I could pop in Frank's
; IP address or something (would need to arrange this
; with Frank, obviously, to make sure it's running and
; I have "permissions" to do it :) and then the
; application would be running on my machine but the
; windows and stuff popping up on Frank's machine...
;
; You could also potentially connect to multiple X
; "displays" at the same time, as the "return value"
; is a "handle" (well, actually a pointer to a
; "display" structure...but this is meant to be "opaque"
; that the application just uses it like a "file
; handle"...which, after all, is an index into the file
; descriptor table, in fact, but, again, you're not
; really supposed to know that and should just treat it
; like an "ID code"...just "some number" which identifies
; which "display" you want to access :)...
;
; In this case, I pass NULL as the parameter, which simply
; connects to the "local" X server...so X and the program
; run on the same machine...but note that, with X's design,
; there is no need to modify the program - other than to
; put a proper "display name" as the parameter to say what
; machine you want to "connect" the program to - to work
; "locally" or "remotely"...X always takes a "client /
; server" view regardless, so it's "uniform" wherever the
; "X server" resides...
;
push byte NULL
call XOpenDisplay
add esp, 4
; Check if returned "handle" is NULL, as that's the "failure"
; indicator and jump on error to the code to print the error
; to the user...
;
cmp eax, byte NULL
je near OpenFailed
; Copy returned display "handle" into variable
;
mov [ Display ], eax
; Create "simple window" call
;
; X provides a more complicated "XCreateWindow" but
; also supplies "XCreateSimpleWindow" which "borrows"
; many of the parameters from the "parent" window...
; a time-saver if, as in this simple example, we don't
; particularly care about anything "fancy"...
;
push byte 0 ; background colour
push byte 0 ; border colour
push byte 0 ; border width
push 300 ; height
push 400 ; width
push byte 50 ; top co-ord
push byte 50 ; left co-ord
; next parameter for "XCreateSimpleWindow" is the
; parent window...so, just sneaking in a quick
; API call to "XDefaultRootWindow" which provides
; us with the proper "handle" to the desktop window,
; which acts as a "parent" for all top-level
; windows (it's all very "strictly hierarchical" in
; X like that, that the desktop is a "root window"
; that's "parent" to all other windows :)
;
push dword [ Display ]
call XDefaultRootWindow
add esp, 4
push eax
push dword [ Display ] ; display handle
call XCreateSimpleWindow ; create window
add esp, 36 ; C clean-up parameters stuff
; Again, check call actually worked by seeing if we
; got NULL rather than a "window handle"...
;
cmp eax, byte NULL
je CreateFailed
; Store away window "handle" for subsequent use...
;
mov [ Window ], eax
; Right, here's something X does that Windows
; doesn't...as X can potentially operate over a
; network, it is concerned about keeping "bandwidth"
; down, where possible...hence, using "XSelectInput"
; I can tell X what types of events this application
; processes...and, simply, X does not bother to
; deliver events that aren't processed by the
; application...after all, what's the point? Wastes
; "bandwidth" sending them around and the application
; isn't going to process it, so you waste all that
; time for nothing...
;
; Indeed, under Windows, where you can't be "selective"
; like this, it really does send every single message
; every single time...and what does the application do?
; Passes it to "DefWindowProc" or, in other words,
; "return to sender"...what a dreadful waste of
; time, eh? Sending messages that we _KNOW_, ahead of
; time, the application is only going to send straight
; back to Windows...X's design is a little smarter than
; Windows on this: The application uses "XSelectInput"
; to say what "events" it does understand and process,
; then it only needs to bother going to the effort of
; sending them when it's actually something the
; application is going to process...rather than doing
; the "round-trip" each and every time, as Windows does,
; it simply asks up front: "what events do you care
; about?" and then doesn't even bother worrying an
; application with "events" that it has no interest in...
;
; This saves "bandwidth" when working over a network
; connection...but, then again, it's also a better design
; for "local" connections too..."events" may be delivered
; very quickly when "local" but, well, it's not "zero time"
; to deliver it (this would violate the laws of physics ;),
; so it is wasting time needlessly to do it the Windows
; way, however small that may be...
;
; Anyway, I simply ask for the "KeyPress" event only, as
; this is a delibrately "brain-dead" simple example program
; that does absolutely nothing useful or impressive
; whatsoever ;)...
;
push KeyPressMask
push dword [ Window ]
push dword [ Display ]
call XSelectInput
add esp, 12
; Now we "map" the window to the "display"...which sounds
; rather "fancy" but just means "ShowWindow", really...
; and are just saying "okay, finished setting things up
; for the window, please show it on the screen" :)...
;
push dword [ Window ]
push dword [ Display ]
call XMapWindow
add esp, 8
; Standard "message loop" of any event-driven program
; which just keeps grabbing "events" off the "queue"
; and "processing" them...
;
MessageLoop:
; Grab the next event off the queue into the "event"
; buffer I created in the data section to house the
; "event" information...
;
; Note another Windows / X difference: In Windows,
; there are "queued" and "non-queued" messages...the
; "non-queued" messages go directly to the "window
; procedure" defined by the "window class" registered
; for that window...you'll notice that we did not need
; to perform any "registering window classes" here...
;
; Simply, X only has "queued events" throughout...this,
; I reckon, is just great because there's no need for
; any silly "window classes" and you're not "forced" into
; using "window procedures"...it's really very simple:
; X provides a "XNextEvent" API which pulls off the next
; "event" from the queue...once in the "buffer" you've
; allocated for the "event information", it's completely
; up to the program how to deal with this...
;
; So, if a simply program with one window, then you might
; just deal with it all directly in the "message loop"
; itself...if you prefer the "window procedure" style then
; just create an ordinary procedure and then call it,
; passing the "event information", for the same
; functionality...it's all in the programmer's hands
; because X simply provides the "get next event" API and
; then the program itself can decide how to process it...
;
push event
push dword [ Display ]
call XNextEvent
add esp, 8
; Was "event" a "KeyPress"?
; If not, loop around again...
;
cmp dword [ event ], KeyPress
jne MessageLoop
; Destroy the window...
;
push dword [ Window ]
push dword [ Display ]
call XDestroyWindow
add esp, 8
CreateFailed:
; Close the "display"
; (e.g. close the connection to X :)
;
push dword [ Display ]
call XCloseDisplay
add esp, 4
jmp Terminate
OpenFailed:
; Print error message if failure to open X "display"
; (yes, I was going to put full "error handling" but
; then gave up that this is, in fact, the only
; condition that gives an error message...a real
; program would be better than that, of course...but
; after starting with "good intentions", it seemed
; too much bother to do it everywhere with the
; program and I gave up ;)...
;
mov eax, 4
mov ebx, 1
mov ecx, StringOpenFailed
mov edx, 27
int 80h
Terminate:
; exit program
;
mov eax, 1 ; function (sys_exit)
xor ebx, ebx ; exit code
int 80h ; make Linux system call
呵呵,不要被吓怕了,汇编代码中每行";"后面的是注释的。和windows程序一样,每个程序中存在创建窗口、消息循环和退出三部分代码的,这段代码也是存在着这些部分的,具体请看注释哦。
把这段代码保存后我们就要使用编译器编译它成可执行文件啦。在linux的终端按照下面的步骤编译连接它。
nasm -f elf -o 2.o 2.asm
gcc -s -nostartfiles -o 2.bin 2.o -L/usr/X11R6/lib -lX11
请注意:linux中命令行都区分大小写。
如果没有提示错误的话,可执行文件2.bin就存在本目录中了,我们来运行它!
./2.bin
回车后,哈哈,窗口出来了!有成就感吧!这是您在linux下的成功编译了汇编代码的Xwindows 程序!恭喜您啦。需要程序为您做的更多?来吧,我们一起学习NASM!
最底层是编辑文挡,光标窗口是终端,黑色的就是我们运行的程序窗口啦
您读了本文后有什么问题可以同作者直接联系,他的联系方式是:
pmason_rose@msn.com
332779423@qq.com
2007年8月18日
--------------------------------------------------------------------------------
欢迎访问AoGo汇编小站:http://www.aogosoft.com 下一篇>>>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -