⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 编译xwindows下的汇编代码 .txt

📁 会变语言实现的一些程序
💻 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 + -