精华内容
下载资源
问答
  • 版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明http://www.tuenhai.com/logs/3203703.htmlHLA安装与设置——汇编语言教程之《汇编语言编程艺术》《汇编语言编程艺术》(The Art of Assembly ...
     版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.tuenhai.com/logs/3203703.html

    HLA安装与设置——汇编语言教程之《汇编语言编程艺术》

    《汇编语言编程艺术》(The Art of Assembly Language)
    介绍了一种高级汇编语言HLA ( High Level Assembly ),最开始HLA 是加州大学的教授用来讲解汇编语言编程和机器组织的一个工具,经过几年的发展,如今已经成为了资深汇编语言程序员编写可读性强、功能强大的汇编程序的开发平台。

    汇编语言编程艺术 可到作者主页去下载英文电子版  http://webster.cs.ucr.edu/  

    tuenhai.com按:我的HLA环境变量设置:
    C:/AUTOEXEC.BAT的内容:

    @echo off
    SET include=d:/masm32/include
    SET lib=d:/masm32/lib;d:/hla/hlalib
    SET path=d:/masm32/bin;d:/hla
    SET ML=/coff /link /SUBSYSTEM:WINDOWS
    set hlainc=d:/hla/include
    set hlalib=d:/hla/hlalib/hlalib.lib
    echo on

    AUTOEXEC.BAT的目标位置设置成:
    %SystemRoot%/system32/cmd.exe /KC:/AUTOEXEC.BAT


    HLA的编辑器一般用RadASM,汉化增强版下载地址:
    http://www.hanzify.org

    下载下来后安装到D:/RadASM, 另hla安装到D:/hla.

    RadASM之路径设置(见hla.ini):

    $A=D:/hla
    $B=$A/
    $D=$R/AddIns
    $H=$A/help
    $I=$A/Include
    $L=$A/hlalib
    $P=$R/Hla/Projects
    $S=$R/Hla/Sniplets
    $T=$R/Hla/Templates
    $M=$R/Hla/Macro
    $E=$R/OllyDBG


    RadASM环境变量tuenhai.com之设置(见hla.ini):
    1=path,d:/hla;d:/masm32/bin;
    2=lib,d:/hla/hlalib
    3=hlainc,d:/hla/include

    RadASM菜单,选项,编程语言,把hla设置到最顶端。


    附录:

    HLA主页:
    http://webster.cs.ucr.edu/

    在线阅读<汇编语言编程艺术>部分章节:
    http://www.ebook520.com/showbooknclass.asp?id=63
    http://act.it.sohu.com/book/serialize.php?id=531#content


    http://utime.blogbus.com/logs/2005/12/1730078.html
    成功安装HLA
    2005-12-21, by utime
    因为是初次安装HLA,所以费了很大的力气才能成功。把收获与应该注意的问题记下来。如果你也是初次安装,并且安装之后不能汇编链接得到

    可执行文件的话,请先认真阅读下面的安装说明。或者直接读我的安装笔记,对照你的安装方法,也能立即找到问题所在。

    安装说明:
    http://webster.cs.ucr.edu/AsmTools/HLA/HLADoc/HTMLDoc/Install.html

    安装环境:
    Windows xp;
    Masm32: 安装到C:/masm32
    Hla:安装到C:/hla

    在阅读下面的注意事项之前,保证你已经正确设置了hla要求的环境变量(hlainc,hlalib,hlatmp)。在DOS提示符下,用path, set等设置,而一

    劳永逸的方法参考下面的1)步。

    1)安装hla后,在DOS下汇编程序时,提示错误“hla既不是命令行,也不是可执行文件”
    解决:在“我的电脑”|“高级”|“环境变量”下加入 Path=C:/hla,因为DOS命令PATH是为系统设置可执行文件路径。

    2)提示错误“ml既不是命令行,也不是可执行文件”
    解决:复制C:/masm32/bin中的四个文件:ml.exe, ml.err, link.exe, mspdb50dll 等到C:/hla文件夹下;

    3)每次打开DOS命令行很麻烦,要多次击键,还要用DOS命令改变当前文件夹。
    解决:先在C:/hla下建立子文件夹/myprojects。然后为DOS命令符建立桌面快捷方式,并为此快捷方式设置起始位置:C/hla/myprojects。

    下次双击DOS命令符快捷方式时,弹出的窗口一定让你满意。

     

    http://community.csdn.net/Expert/topic/4919/4919070.xml?temp=.1769678
    搞汇编的人都知道一本非常牛的书: AOA !
    这本AOA是用HLA讲述汇编的。那么什么是AOA?什么是HLA?

    ○  HLA简介

    HLA,英文"High Level Assembler"(高阶汇编)的缩写,即所谓高级语法的汇编,它将一些高级语言中的特性加入汇编编写中,但它在最终的

    编译连接时还是要用到MASM的编译器和连接器。

    更进一步的解释请参看:
    http://webster.cs.ucr.edu/AsmTools/HLA/index.html

    强烈建议没装过、用过HLA,都用用HLA。没看过《The Art of Assembly Language》(汇编语言的艺术)这本书的都看看。HLA是最牛逼的汇编

    了!《The Art of Assembly Language》是非常牛的一本汇编书了!

    安装HLA,只要三、五分钟就搞定,然后你就可以用它编程了,非常爽!都来试试吧。

    ●  HLA的安装

    1.下载并安装MASM32

    http://www.masm32.com

    去下载一个MASM32,并安装它。

    2.下载并安装HLA

    先到
    http://webster.cs.ucr.edu

    点击“High Level Assembly”的链接,打开http://webster.cs.ucr.edu/AsmTools/HLA/index.html

    再点击“Download HLA”的链接,打开http://webster.cs.ucr.edu/AsmTools/HLA/dnld.html

    再找到“Windows Users”下的“HLA Installation Program”,比如hlasetup.exe,然后下载它。

    再安装它,安装时选择的目录不要带空格,比如不要装在C:/Program Files,而装在C:/Inetpub可以。

    3.设置HLA

    到MASM32的bin子目录下,把其中的ml.exe、ml.err、link.exe、mspdb50.dll四个文件复制到HLA所在目录。注意是复制而不是移动。

    然后再到MASM32/lib目录下,把其中的gdi32.lib、kernel32.lib、user32.lib三个文件复制到hla/hlalib目录下(如果原本就有这些文件,可

    覆盖它们)。注意是复制而不是移动。

    设置并确认以下四个系统环境变量:

    set hlainc=c:/hla/include
    set hlalib=c:/hla/hlalib/hlalib.lib

    (安装程序可能已把以上两个系统环境变量设好,不必再改动了)

    set lib=c:/hla/hlalib; 《some text》

    (安装程序可能已把以上这个系统环境变量设好,但需要检查设置的对不对,有没有重复的地方)

    set path=c:/hla; 《some text》

    (一般这个系统环境变量的新增部分需要手工添加,注意如果同时安装了Cygwin,要确保HLA的路径在Cygwin之前,否则Cygwin也带有link.exe

    ,它会先于HLA被执行,导致HLA连接时出错)

    4.运行HelloWorld测试HLA

    编辑并存盘一个HelloWorld.hla文件,把它存到c:/hla/test,内容如下:

    program HelloWorld;
    #include( "stdlib.hhf" );
    begin HelloWorld;
    stdout.put( "Hello, World of Assembly Language", nl );
    end HelloWorld;

    注意:Randall Hyde在他的AOA(The Art Of Assembly)一书里的上述源码中,英文引号(" ")都变成了中文引号(“”),需要改正过来才

    可无错运行。我给出的代码是没这个问题的,你拷贝过去就可直接无错运行了。

    编译并运行它:

    C:/hla/test>hla HelloWorld.hla
     Assembling: HelloWorld.asm

    C:/hla/test>HelloWorld
    Hello, World of Assembly Language

    C:/hla/test>

    进一步修炼HLA,看《The Art of Assembly Language》这本书。

    参考网址:
    http://webster.cs.ucr.edu


    HLA是真正意义上的汇编,你只看到了我本贴的 hello world,就下了结论未免失之偏颇.

    其实你应该认真看完那本很牛的AOA, 就会知道你现在的认知是多么地错了!

    呵呵, 学下 Randall Hyde 的 "AOA" 吧.他是搞汇编的大虾都无人不知无人不晓的一本牛书,它的中文版有没有不知道,反正英文版是作者免费

    提供下载的:

    http://webster.cs.ucr.edu/AoA/index.html


    分不同版本(根据操作系统), 其中Windows版的"AOA"电子书下载:
    http://webster.cs.ucr.edu/AoA/Windows/index.html

    有html,pdf,chm几个版本可以选择


    "AOA"已经很牛了,但Randall Hyde最牛的书还是更高级修炼的"The Write Great Code"系列,到目前为止出了4卷本:
    http://webster.cs.ucr.edu/WriteGreatCode/index.html

    学完AOA再学 Write Great Code,感到他实在太牛了,强人啊

    牛人Randall Hyde的网站:
    http://webster.cs.ucr.edu
    以上的下载和书讯都是他这个站的,HLA也在这里下载,牛人啊!

    Write Great Code: Understanding the Machine, Volume I
    第1卷我在emule找到下载的,不敢私藏,拿出来与大家共享,源很多速度够快,如果需要也先下吧


    ed2k://|file|Write%20Great%20Code,%20Volume%201%20-%20Understanding%20the%20Machine%20(No%20Starch%20Press,%

    202004).chm|8645090|5518217462E6703BD1CC829F96051C42|/

    HLA学习笔记(1)

    http://www.vckbase.com/document/viewdoc/?id=1578

    作者:lostpencil

    HLA 介绍

      HLA是高级汇编语言(High level assembly)的缩写,个人感觉这是一门和c语言有着很大的相似性的汇编语言。他在汇编语言的基础上构建了自己的标准库,使得软件的汇编开发的复杂度大大的减少了,又不影响汇编超级主动的性质。凭我个人短暂的体验来看,最大的不足就是和64位机器的兼容问题,因为它本质上将HLA代码转换成了32位机器的汇编指令,然后通过那些指令操作机器,32位机器和64位机器指令的微小差异,常常弄的很头疼,有时候需要逐个检查生成的汇编代码,修该了才能运行,所以建议,如果不太熟悉这种东西的时候学习的时候还是用32位的机器比较好,可以省去不少麻烦。总之,感觉用这门语言作为汇编语言学习的入口,恰到好处

    HLA 的安装

      运行HLA需要的相关软件和相关介绍资料,都可以在http://webster.cs.ucr.edu/AsmTools/HLA/index.html相关的页面找到下载,顺便说出来它是免费的。
      Windows下面的HLA安装比较简单就不说了,简单介绍我的 LINUX 环境下的安装。(其实上面那个网站上面说的很明白,即便有一些微小差别也可以轻松搞定,如果你熟悉linux环境的话)
      下载就不说了,你需要下载的是hla.tar.gz,文件名会因为版本不同有微小的差别。专家们都说的是放在/usr/hla,就这么放好了。然后cd 到/usr,释放文件( gzip -d hla.tar.gz,现在可能会有不同,我记不清我当时怎么做的了,这步好象可以省略,因为文件的格式变了)然后tar xvf hla.tar,基本安装就搞定了 。当然忘了说了你的usr文件对你来说,可能会有一些权限的问题,一般都是在root下做上面操作,然后更改文件权限,使得普通用户可以访问,简单的chmod 777 *就可以,不过要改变整个文件下所有文件的权限,你还需要加上-x参数(参数忘了,自己man chmod吧),接着就是配置相关文件。这时最好用普通用户,因为该系统文件的时候root是和可怕的东西。切换到/home/你的用户文件下,ls -a 找到.bashrc文件,在PATH变量定义的地方追加:/usr/hla(安装hla的路径),然后追加这样两条:

    hlalib=/usr/hla/hlalib/hlalib.a
    export hlalib
    hlainc=/usr/hla/include
    export hlainc
    后面的路径都是你的实际路径
    然后在/usr/hla下面建一个tmp文件夹(放代码的地方)
    继续在.bashrc文件里面增加:

    hlatemp=/tmp
    export hlatemp
    (以上变量声明的文件可能和实际系统有所出入,你打开看起来比较像的文件,逐个比较下,看清楚他们的规则,然后增加在适当的地方才不会出错,尝试之前先做个备份)
    基本上就好了,你到控制台输入,hla回车,会开到相应的hla提示信息了。

    经典的开始

    来写个hello word吧
    cd 到/usr/hla/tmp 然后用vi写一个hw.hla文件,在里面增加如下代码:

    program HelloWorld;
    #include( "stdlib.hhf" )
    begin HelloWorld;

    stdout.put( "Hello, World of Assembly Language", nl );

    end HelloWorld;
      保存,然后hla hw.hla,你就会看见标准输出上有Hello, World of Assembly Language,我实际操作的时候提示n1是未定义的宏,因为也

    刚学不太久,没有仔细琢磨,把nl去掉就没事了,不过也不换行了。这时,你察看你的tmp文件,会多了很多个文件,根据他们的文件类型名很

    容易知道他们是什么,看看那个纪录汇编指令的文件吧,哈哈,原来一个简单的hello world 用到的指令也不少呢。

    后记

      目前我也刚开始学这个东西,欢迎更多的人加入这个行列,共同指点下,偶基础比较差,学起来有些困难。不过我会坚持写完这个笔记的

    ,over!

    http://community.csdn.net/Expert/topic/4874/4874821.xml?temp=.2486536


    最近我看到不少兄弟在问关于 HLA 学习的事,他们大多买了<<汇编语言编程艺术>>这本书,作者是美国的 Randall Hyde。这本书写的总的来说还是不错的。刚开始的时候比较简单,有些简单的地方又说的略显啰嗦。但如果你耐心看一段时间就能体会其中乐趣。虽然该书有些地方讲的让初学者感到困惑:比如讲到 类和对象汇编实现的时候,开始的一大部分用来做上机实操时得到关于类方法的执行都是会出错的,因为有个关键地方没有设置,即:

    VMT(classname);
    mov(&tBaseClass._VMT_,bc.pVMT_);

    而这个设置在后面才会讲到,但开始却没有丝毫提起,所以会让很多人以为是hla实现上有问题,其实不然。
    当然本书自身翻译的不自然和漏字错字也还是存在的,这也算翻译作品的通病吧。而且译者好像缺乏了一点幽默感(我没看过英文原著),但从某些句子段落的咀嚼似乎又能让你会到原作作者的幽默天才(很多原作作者的语言都是很生动和诙谐幽默的,例如另一本:<<WIN32 API 编程 for VB>>)。但不管如何该书还是很有看头的,其中还探讨了使用 HLA 强大的编译时语言编写高级语言语法的功能,还有浮点指令,MMX指令的用法,类和对象的实现等等。

    我写此作的目的是希望正在学习 HLA 的朋友能够将遇到的问题和学习的经验和心得和大家共享,本人才疏学浅,通假字连篇,所以不当之处恳请各位多多指出,在此谢过了。

    我想先抛砖引玉先说2点:
    1. <<汇编语言编程艺术>> 这本书中使用的是 masm32 的编译器,但书中对 win32 SDK  编程好像只是一笔带过,并无详细说明,我在这里就先给出对于 win32 SDK 的简单
       实现,相信大家可以举一反三:

    //* * * * * * * * * * * * * *
    //code by hopy|侯佩         *
    //to use Win32 API with HLA *
    //2006-07-12                *
    //* * * * * * * * * * * * * *

    program Win32ApiNow;
    #include("w.hhf");
    #include("wpa.hhf");

    const
    txt:string:="I'm Hopy";
    cp:string:="windows XP";

    begin Win32ApiNow;
    w.MessageBox(NULL,txt,cp,w.MB_OK);
    end Win32ApiNow;

    (未完待续...以前画漫画的时候经常为这4个字给人骂死...呵呵)


    2 关于 enum 的研究。书上 P154 页略微提到了一点 HLA 对枚举表达的实现,但作者
      同时指出内部是使用 8bits 变量存放 enum 的元素,所以enum元素数量不能超过
      256个,有趣的是在 P155 页的脚注上作者却提示:HLA 提供了一个机制,该机制可以
      指定 enum 数据类型占用 2 个或 4 个字节的空间,到此本书再也闭口不提如何达到
      该目的。那么到底可不可以让枚举占用超过1字节的空间呢?

      我在 HLA 编程指南中找到这么一段话(原话):
     
      By default, HLA uses eight-bit values to represent enumerated data types. This means that you can represent up to 256 differentsymbols using an enumerated data type. This should prove sufficient for most applications. HLA provides a special"compile-time variable" that lets you change the size of an enumerated type from one to two or four bytes. In theory, all you’vegot to do is assign the value two or four to this variable and HLA will automatically resize the storage for enumerated types tohandle longer lists of objects. In practice, however, this feature has never been tested so it’s questionable if it works well. If youneed enumerated lists with more than 256 items, you might consider using HLA const definitions rather than an enum list, just to be on the safe side. Fortunately, the need for such an enum list is exceedingly remote.

    上面的确提到 HLA 可以对超过256个枚举元素的支持,其主要思想为(部分翻译如下):

    HLA 自动地根据 enum 元素的数量改变空间的大小,理论上可以支持超过 256 个枚举元素。但实际上不管怎样这个特性从来没有被测试过,它有可能工作不正常。如果您要
    创建超过 256 个枚举元素,您可能在 const 段中定义更好一些...

    观看不试是没有用的,下面我创建了一个含有 500 个元素的 enum 类型,为了简便起
    见,我使用了 HLA 的编译时语言的支持,而不是真的手工输入500个元素(谁叫偶懒哩):

    program EnumTest;
    #include("stdlib.hhf");

    type
    //以下是创建500个元素的 color 枚举:
    color:enum{
    ?i:=0;
    #while(i<500)
    @text("a"+ string(i)+",")
    ?i:=i+1;
    #endwhile
    a500
     };

    static
    EC:color:=a500;

    begin EnumTest;
    //nothing...
    end EnumTest;

    结果是编译无法通过:

    F:/HLA>hla a.hla
     Assembling: a.asm
    a.data.inc(2) : error A2071: initializer magnitude too large for specified size
    Error returned by Assembler = 1

    真的行么?下面我将 EC:color:=a500; 改为 EC:word:=a500; 如下:

    program EnumTest;
    #include("stdlib.hhf");

    type
    //以下是创建500个元素的 color 枚举:
    color:enum{
    ?i:=0;
    #while(i<500)
    @text("a"+ string(i)+",")
    ?i:=i+1;
    #endwhile
    a500
    };

    static
    EC:word:=a500;

    begin EnumTest;
    //nothing...
    end EnumTest;

    OK,编译成功,用 ollydbg 查看, EC 变量的值正确的被赋为: 01f4h


    1 HLA 用的就是 masm32 的汇编器,只不过内部有个"翻译器"将含有 HLA 语法 的 .hla 文件翻译成 标准的 masm 语法的 .asm 文件。

    2 HLA 旨在探讨汇编对高级语言中一些功能的实现,比如 低级条件语句和高级条件语句的转换,汇编对高级语言中类与对象的支持,在HLA 的编译时语言中还讨论了编写高级语言语法器的可能性。

    3 我同意楼上的观点,在大部分的工作中,的确不需要汇编的存在,而我也只在研究或追求速度空间的 cool 时才摆弄汇编。
      若楼上有兴趣,可以看看我写的关于 五角星问题和背包问题的汇编解法。

    3 关于 HLA 中的 intmul 指令,大家如果在 intel 指令手册中找的话,结果可能会失望,因为没有该条指令。其实他只是 imul 的变种(异型?)之一:

      imul r32,r/m32,imm8/32

    4 在看到移位指令的时候,我就在想是否可以不用位指令来实现移位(bt之类的指令也不用)。答案是肯定的,以下是左移一位的代码:

    program mainmy;
    #include("stdlib.hhf");

    readonly
    bitstr:byte[8]:=[%0000_0001,%0000_0010,%0000_0100,
            %0000_1000,%0001_0000,%0010_0000,
            %0100_0000,%1000_0000];

    var
    mb:byte;

    procedurelm1(var mb:byte);
    var
    tmpa:byte;
    tmpb:byte;
    tmpi32:int32;
    beginlm1;
    push(eax);
    push(ebx);
    mov(mb,eax);
    mov([eax],al);
    mov(al,tmpb);
    mov(al,tmpa);

    mov(6,tmpi32);
    while(tmpi32>=0) do
    mov(tmpi32,ebx);
    and(bitstr[ebx],al);
    mov(bitstr[ebx+1],al);
    jnzt0;
    not(al);
    and(al,tmpb);
    jmpt1;
    t0:
    or(al,tmpb);
    t1:
    dec(tmpi32);
    mov(tmpa,al);
    endwhile;

    and(%1111_1110,tmpb);
    mov(mb,eax);
    mov(tmpb,bl);
    mov(bl,[eax]);
    pop(ebx);
    pop(eax);
    end         lm1;

    begin mainmy;

    mov(%0101_0111,mb);
    stdout.put("the value before transfer is ",mb,nl);
    lm1(mb);
    stdout.put("after transfer the value is ",mb,nl);

    end mainmy;


    5 我在上面说过了 HLA 的编译时语法的功能是很强的,现在做一个小的实例是通过
      编译时宏将 ascii字符串 转换成 宽字符串。要说明的是这个转换很简单,只是一
      个小例子其中还有很多没考虑到的地方:

    program test0;
    #include("stdlib.hhf");

    #macroctrlstr(thestr);
    ?maxlen:=@length(thestr);
    ?i:=0;
    @text("ustr:char[maxlen*2+2]:=[")
    #while(i<maxlen)
    ?strnow:=@substr(thestr,i,1);
    @text("#0,'"+strnow+"',")
    #print(strnow)
    ?i:=i+1;
    #endwhile
    @text("#0,#0];")
    #endmacro;

    static
    ctrlstr("kinds");

    begin test0;

         //do nothing ...

    end test0;

    展开全文
  • 汇编语言编程——DOSbox

    千次阅读 多人点赞 2019-05-06 20:44:58
    汇编语言编程——DOSbox         使用DOSbox编写汇编程序步骤 1.安装DOXbos 点击Next, 点击Next,自己选择安装路径最好不要安装在C盘。 点击Install进行安装。 安装完成,点击Close。 在桌面就可以找到...

    汇编语言编程——DOSbox

            使用DOSbox编写汇编程序步骤

    1.安装DOSbox

    在这里插入图片描述
    点击Next,
    在这里插入图片描述
    点击Next,自己选择安装路径最好不要安装在C盘。
    在这里插入图片描述
    点击Install进行安装。在这里插入图片描述
    安装完成,点击Close。
    在这里插入图片描述
    在桌面就可以找到快捷方式,双击就可以打开程序。

    2.编写汇编程序

            推荐大家用Notepad++这个编辑器来编写汇编代码,首先创建一个文本文件命名文件(例如:hello.asm),注意要打开文件的扩展名,把后缀改成XXX.asm文件的形式。然后用Notepad++编辑器打开编写程序并保存。

    在这里插入图片描述
    在这里插入图片描述
    下面是“hello world”的汇编程序代码

    ;这个是8086的写法
    data segment ;这里定义一个数据段
         tab db 'hello world$' ;这里用内存存放字节数据 'hellow world!',$用来判断字符串是否输出完毕
    data ends ;数据段的结束标志
    
    code segment ;这里定义了一个代码段
        assume cs:code, ds:data ;这里把程序中定义的段与对应的段寄存器关联起来
        
    start: ;这里是一个标号,根据end后面的标号判断这里是程序的开始位置
          mov ax,data
          mov ds,ax ;这里把数据段的地址放到数据段寄存器ds中
          lea dx,tab ;dx中放将要显示数据的偏移地址
          mov ah,9h
          int 21h ;调用21号中断的9号功能来显示字符串
          mov ah,4ch
          int 21h ;程序返回在这里插入图片描述
    code ends ;代码段的结束语
        end start ;定义程序从哪个标号处开始执行
    

    3.运行程序

            首先,要在磁盘中(D,E,F盘)创建一个文件夹ASM,把运行程序需要的文件添加进去。要处理汇编文件,masm.exe宏汇编工具,link.exe连接程序,debug.exe调试程序,edit.exe编辑工具。

    在这里插入图片描述
    然后打开DOSbox软件在这里插入图片描述
    输入mount C C:\ASM,挂载带C盘ASM所在的位置,如果你的ASM文件夹在其他盘输入他的位置就可以。
    在这里插入图片描述
    挂载成功后,输入C:在这里插入图片描述
    这样就输入系统命令操作文件,输入命令DIR,可以查看文件夹中的文件。
    在这里插入图片描述
    输入MASM hello.ASM,打开hello.ASM文件编译,一直按回车,完成编译。
    在这里插入图片描述
    接下来输入LINK hello.obj命令生成obj执行文件。
    在这里插入图片描述
    在这里插入图片描述
    输入hello.exe,运行文件。
    在这里插入图片描述
    运行成功,还可以输入debug命令查看程序运行的一些数据
    在这里插入图片描述
    好了以上就是汇编程序的编写和运行过程。
    汇编软件下载和用的文件可以在百度云盘中下载
    链接:https://pan.baidu.com/s/10yVJQRxsNrPhQ5BN73MDEQ
    提取码:4757
    复制这段内容后打开百度网盘手机App,操作更方便哦

    展开全文
  • Windows 汇编语言编程教程

    万次阅读 2005-10-30 11:34:00
    2005.7.10Windows 汇编语言编程教程Version 1.02 Copyright@2005,Jeff Huang.All rights reserved Translator:fqh 2005.7.10 JEFF HUANG 作,fqh译 目录介 绍 …………………………………………………………...

    2005.7.10

    Windows 汇编语言编程教程

    Version 1.02

     

    Copyright@2005,Jeff Huang.All rights reserved

     

    Translator:fqh  2005.7.10

     

     

    JEFF HUANG 作,fqh译

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     


    目录

       ……………………………………………………………………………2

    为什么选用汇编语言 …………………………………………………………2

    为什么选择Windows系统……………………………………………………2

    Ⅰ开始学习之旅 ……………………………………………………………….…3

    编译器   ………………………………………………………………………3

    编辑器 …………………………………………………………………………3

    Ⅱ第一个程序  ……………………………………………………………………4

    控制台程序 ……………………………………………………………………4

    窗体程序 ………………………………………………………………………6

    ADDR OFFSET  ………………………………………………………6

    Ⅲ汇编基础…………………………………………………………………………7

    cpu寄存器 ……………………………………………………………………7

    指令集基础 ……………………………………………………………………8

         Push Pop…………………………………………………………………8

         Invoke   ……………………………………………………………………9

    程序例子 ………………………………………………………………………9

    IV. 窗体程序基础…………………………………………………………………10

    预备知识………………………………………………………………………10

         ……………………………………………………………………………10

         过程…………………………………………………………………………10

    变量…………………………………………………………………………10

    一个简单的窗体程序…………………………………………………………11

    IV. 深入汇编和系统………………………………………………………………13

    字符串操作……………………………………………………………………13

    文件管理………………………………………………………………………13

         存储…………………………………………………………………………14

       程序例子……………………………………………………………………14

    控制……………………………………………………………………………15

    附加资源 …………………………………………………………………………16

         互联网………………………………………………………………………16

         书籍…………………………………………………………………………16

         MASM32……………………………………………………………………16

         MSDN………………………………………………………………………16

         新闻组………………………………………………………………………16

         IRC …………………………………………………………………………16

     

     

     


    “This is for all you folks out there,who want to learn the magic art of Assembly programming”

    -MAD

     

    我最近才开始学习windows系统汇编语言编程,这个教程是我在学习汇编语言的过程中写下来的。我阅读大量的在线教程、书本,以及通过新闻组以及IRC通讯工具请问他人,本人就是通过这些方式学习汇编语言的。互联网上有很多的汇编编程的教程,但这些教程只是侧重于X86汇编。因为这些教材都假定读者已经掌握了高级编程语言以及基本的计算机系统知识。

     

    为什么选用汇编语言?

    汇编语言具有若干的特色,使得在某此情况下,汇编语言是一种很好的选择。

    1 快速 汇编语言程序运行的速度比高级语言程序要快。通常,要求运行效率高的子程序是用汇编语言编写的。

    2 强大 运用汇编语言,你能得到不受限制的权力。相对的,高级语言则有种种限制,在实现某些特定的要求时变得困难。

    3 体积小 汇编语言程序通常比其他语言程序要小得多。这种特性在空间有限的情况下是非常有用的。

    为什么选择Windows系统?

    在任何操作系统和处理器模式下,都可以编写相应的汇编语言程序的。但是当前,多数人在使用基于x86处理器的Windows系统,所以从编写运行于此种环境下的程序开始我们的教程。一旦一种汇编语言的基础知识掌握了,我们就会很容易写出在其他运行环境下汇编程序。

    第一章

    Ⅰ开始学习之旅

    编写汇编程序,我们必须具备一些工具,它们是编译器以及编辑器。我们选择了一些能胜任这些工作的运行于Windows系统的工具如下。

    编译器

    编译器能把写下的汇编程序代码转换成机器码。通常,它附带有一个连接器。连接器用来连接可编译文件并从中生成可执行文件。Windows系统的可执行文件是以.exe为后缀的。下面给出一些流行的编译器:

    1 MASM 这个编译器是本教程所选用的,在学习本教程的过程中,你可以使用它。它原先由微软公司开发,现在被包括在MASM32v8程序包内了。MASM32v8程序包还包括了其他的工具。你可以从这个网址得到它:http://www.masm32.com/.

    注意:教程中有一些指令和宏指令,只有在MASM编译器才是有效的,所以强烈建议您从开始学习时选用MASM

    2. TASM 这是另一个受欢迎的编译器。由Borland公司开发,现在依然是个商业软件,所以你不能免费地获取到它。

    3. NASM 一个免费开放源码的编译器,它也能在其他系统平台上使用。它可以从这个网址获取到http://sourceforge.net/projects/nasm/ 记住

    编辑器

    编辑器是在编译前编写程序代码的软件。编辑器可以个人自由选择。现在在很多种编辑器,你可以试用一下它们并选择一种你喜欢的。

    1 Notepad 记事本,Windows系统自带的。虽然它缺少很多功能,但它使用简便。

    2 Visual Studio 它不是免费的编辑器,但它出色的语法高亮显示功能能让你的代码更易于阅读。

    3. 其他 还有很多其他的编辑器,在些不一一列出它们的名字。其中一些很受欢迎:

    a. Ultraedit (我个人最喜欢的e) http://www.ultraedit.com/

    b. Textpad http://www.textpad.com/

    c. VIM http://www.vim.org/

    d. Emacs http://www.gnu.org/software/emacs/emacs.html

    e. jEdit http://www.jedit.org/


     

    第二章

     


    Ⅱ第一个程序

    现在我们有了自己的工具,打开你的文本编辑器,跟着下面的介绍,开始学习编程吧。这是世上最普通的程序,“Hello World”程序。

    控制台程序

    控制台程序是运行在系统控制台的(也就大家所知的命令行)。为创建这个程序,首先粘贴下面的代码到你的文本编辑器上,并保存为文件“hello.asm”。

    .386

    .model flat, stdcall

    option casemap :none

    include /masm32/include/windows.inc

    include /masm32/include/kernel32.inc

    include /masm32/include/masm32.inc

    includelib /masm32/lib/kernel32.lib

    includelib /masm32/lib/masm32.lib

    .data

    HelloWorld db "Hello World!", 0

    .code

    start:

    invoke StdOut, addr HelloWorld

    invoke ExitProcess, 0

    end start

    现在,通过开始菜单,点“运行…”选项,输入“cmd”(没有引号)并回车,就能进入到命令行。接着在cmd下转到保存有”hello.asm”的目录,输入"/masm32/bin/ml /c /Zd /coff hello.asm"。期望编译器不会提示错误,你的程序能被正确编译!然后,我们还得连接它,所以接着输入"/masm32/bin/Link /SUBSYSTEM:CONSOLE hello.obj"。祝贺你!你已经成功编译了第一个汇编语言程序。在文件夹里出现了一个中Hello.exe的文件。在命令行下打"hello"来运行你的程序。它会输出"Hello World!"。可见,为了显示"Hello World!",我们只要编写很少的代码就可以了。

    这些代码都起了什么作用呢?让我们一行一行地看下去。

    .386

    这条指令的作用是告知编译器使用.386指令集。当前,几乎没有处理器使用比.386更老的指明令集了。我们还可以选择使用.486.或586,但是.386是兼容性最好的指令集。


    .model flat, stdcall

    .MODEL 是一条指定你程序的内存模式的汇编指令。Flat是一种方便的系统程序模式,因为在这种模式下不再区分远指针(far)和近指针(far)。Stdcall 是一种系统函数传递参数的方法,它意味着你得以从右到左的顺序传递你的参数。

    option casemap :none

    强制你的程序代码大小写敏感,这意味着Hello和hello被看做不同的。很多高级编程语言同样是大小写敏感的,所以这是个编程的良好习惯。

    include /masm32/include/windows.inc

    include / masm32/include/kernel32.inc

    include /masm32/include/masm32.inc

    这是系统程序必需的包含文件。windows.inc通常必须包含的,因为它包含了Win32 API常量和定义的声明。kernel32.inc包含了我们所使用的ExitProcess函数。masm32.inc包含有StdOut函数。StdOut函数不是Win32函数,它是MASM32v8新增进去的。

    includelib /masm32/lib/kernel32.lib

    includelib /masm32/lib/masm32.lib

    函数依赖库,基于这个目的,这些库得包含进去。

    .data

    程序中所有初始化的数据必须放在这条指令下面。此外,还有别的指令比如.data?和.const。它们分别位于未初始化数据和常量的前面,但是,在我们的”Hello World”程序中并没有用到它们。

    HelloWorld db "Hello World!", 0

    db代表“字节”,并声明HelloWorld为一个字符串。"Hello World!"后面跟着一个”NULL”字母,这是因为ANSI字符串必须以NULL结尾。

    .code

    这代表程序代码段的开始。

    start:

    你程序的代码位于这个标号的后面,但位于” end start”前面。

    invoke StdOut, addr HelloWorld

    Invoke调用一个函数及其参数,addr HelloWorld位于它后面。这一行所做的是传递"Hello World!"的地址和调用StdOut。注意StdOut函数只是在MASM32中有效的,它是一个调用其它函数来输出文件的宏。在别的编译器里,你得使用更多的代码并要用到win32函数WriteConsole.。

    invoke ExitProcess, 0

    显而易见,它传递参数0到ExitProcess函数,从而退出进程。
    窗体程序

    我们也可以编写一个有窗体版本的“Hello World”程序。粘贴下面文本到你的文件编辑器里并保存为文件"hellow.asm".

    .386

    .model flat, stdcall

    option casemap :none

    include /masm32/include/windows.inc

    include /masm32/include/kernel32.inc

    include /masm32/include/user32.inc

    includelib /masm32/lib/kernel32.lib

    includelib /masm32/lib/user32.lib

    .data

    HelloWorld db "Hello World!", 0

    .code

    start:

    invoke MessageBox, NULL, addr HelloWorld, addr HelloWorld, MB_OK

    invoke ExitProcess, 0

    end start

    现在,再打开命令行并转到"hellow.asm"所在目录。输入"/masm32/bin/ml /c /Zd /coff hellow.asm"回车,接着输入"/masm32/bin/Link /SUBSYSTEM:WINDOWS hellow.obj"并回车。注意,subsystem是WINDOWS不再是CONSOLE。这个程序弹出一个显示"Hello World!"的信息框。

    与控制台版相比,窗体版本的代码只有3行是不同的。其中有两行把masm32包含文件和库文件更换为user32包含文件和库文件,这是因为我们现在是使用MessageBox函数,而不是使用StdOut了。第3个不同的行是用MessageBox函数代替了StdOut函数。不同之处就这么多而已!

    ADDR OFFSET

    在我们“Hello World!”程序例子中,我们使用了'addr' 来获取字符串"Hello World!"的地址。还有另外一个类似的指令'offset',虽然两者的目的都是在程序执行中获取变是变量的地址。它们主要的区别是'offset' 只能获取全局变量的地址,然而addr能获取全局变以及局部变量的地址。然而我们不讨论局部变量,所以不用担心这种区别。但是我们还是要记住这种区别的。

    第三章

    汇编基础

    cpu寄存器

    现在我们已经能够编写并运行一个简单的程序了。让我们转到本教程的核心内容-汇编基本语法吧。你要写出自己的汇编程序,这些基本的知识是要掌握的。     32位通用寄存器有8个。它们其中前面四个也就是eax,ebx,ecx,edx,也能用它们16位或8位的名字形式进行存取。比如,ax存取eax的低16位,al存取低8位,还有ah存取的是9到16位。其余的寄存器也能以类似的方式进行存取。就如大家想象的那样,这些通用寄存器虽然大多有专用的用途,但它们有通用的地方。

    地址

    名称

    描述

    EAX*

    累加寄存器

    进行计算操作和保存数据结果

    EBX

    基址寄存器

    指向数据寄存器中的数据

    ECX*

    计数寄存器

    字符串以及循环的计数

    EDX*

    数据寄存器

    输入/输出的指针

    ESI

    源变址寄存器

    字符串操作中的源指针

    EDI

    目的变址寄存器

    字符串操作中的目的指针

    ESP

    堆栈指针寄存器

    堆栈指针,不能人为使用它

    EBP

    堆栈基址寄存器

    指向堆栈中的数据

     

    注意:虽然它们被称为通用寄存器,但是只有那些标有*号的才能在窗体程序编程中使用。

     

     

     

     


    下面是6个16位的段寄存器。它们定义在存储器的段。

    地址

    名称

    描述

    CS

    代码段寄存器

    保存要运行的指令

    DS,ES,FS,GS

    数据段寄存器

    数据段

    SS

    堆栈段寄存器

    当前程序的堆栈

     

    最后,还有2个32位的没有归类的寄存器

    地址

    名称

    描述

    EFLAGE

    标志寄存器

    状态,控制,系统标志

    EIP

    指令指针寄存器

    下一个要执行的指针的偏移

     


    指令集基础

    x86指令集非常宏大,但是我们通常并没全都使用到了它们。下面介绍一些我们应该掌握的指令。

    指令

    描述

    ADD* reg/memory, reg/memory/constant

    把两个操作数相加并把结果保存进第一个操作数。如果有进位的话,它会设置CF标志位

    SUB* reg/memory, reg/memory/constant

    第一个操作数减去第二个操作数,并把结果保存到第一个操作数里

    AND* reg/memory, reg/memory/constant

    两个操作数逻辑与,并把结果存到第一个操作数里

    OR* reg/memory, reg/memory/constant

    两个操作数逻辑或,并把结果存到第一个操作数里

    XOR* reg/memory, reg/memory/constant

    两者异或,并把结果存到第一个操作数里。注意你不能对

    两个存储器操作数进行异或操作

    MUL reg/memory

    操作数与累加器寄存器相乘,而后把结果存进累加器寄存

    DIV reg/memory

    累加器寄存器被操作数除并把结果存到累加器

    INC reg/memory

    操作数的值增1并把结果存进操作数

    DEC reg/memory

    操作数的值减1并把结果存进操作数

    NEG reg/memory

    操作数的值取补并把结果存进操作数

    NOT reg/memory

    操作数的值取反并把结果存进操作数

    PUSH reg/memory/constant

    把操作数压进堆栈顶端

    POP reg/memory

    弹出堆栈顶端的值并保存到操作数

    MOV* reg/memory, reg/memory/constant

    把第二个操作数的值保存到第一个操作数里面

    CMP* reg/memory, reg/memory/constant

    第一个操作数减第二个操作数,并设置相应当的标志位。通常与JMP,REP等指令一起使用

    JMP** label

    跳转到标号处

    LEA reg, memory

    取第二个操作数的地址偏移,并把结果保存进第一个操作数

    CALL subroutine

    调用另一个过程直到程序返回

    RET

    程序返回到调用者

    INT constant

    调用操作数指定的中断

    *指令不能有两个存储器操作数

    **这个指令可以结合条件来使用。比如,JNB(不小于),是只有在CF=0这一条件下才会跳转。

    最新的全部指令集参考可以从下面这个网址得到

    http://www.intel.com/design/pentium4/manuals/index.htm.

    Push Pop

    Push和pop是操作堆栈的指令。Push获取一个数据并把它压进堆栈的顶端。Pop获取堆栈顶端的数据,弹出并保存它。因此,堆栈是使用一个先进后出的存取方式(LIFO)。堆栈是计算机中一个常见的数据结构,所以如果你在编程过程中对堆栈操作感到不顺手的话我建议你先掌握这一知识。
    Invoke

    InvokeMASM特有的一个伪指令。它使得在调用函数前不必先传递参数。这让我们省略了很多的代码。

    举个例子说明如下

    invoke SendMessage, [hWnd], WM_CLOSE, 0, 0

    等效于:

    push 0

    push 0

    push WM_CLOSE

    push [hWnd]

    call [SendMessage]

    程序例子

    下面是一个完整的程序。它说明了如何去使用指令和寄存器。看看是否全部弄懂了它。

    .386

    .model flat, stdcall

    option casemap :none

    include /masm32/include/windows.inc

    include /masm32/include/kernel32.inc

    include /masm32/include/masm32.inc

    includelib /masm32/lib/kernel32.lib

    includelib /masm32/lib/masm32.lib

    .data

    ProgramText db "Hello World!", 0

    BadText db "Error: Sum is incorrect value", 0

    GoodText db "Excellent! Sum is 6", 0

    Sum sdword 0

    .code

    start:

    ; eax

    mov ecx, 6 ; set the counter to 6 ?

    xor eax, eax ; set eax to 0 0

    _label: add eax, ecx ; add the numbers ?

    dec ecx ; from 0 to 6 ?

    jnz _label ; 21

    mov edx, 7 ; 21

    mul edx ; multiply by 7 147

    push eax ; pushes eax into the stack

    pop Sum ; pops eax and places it in Sum

    cmp Sum, 147 ; compares Sum to 147

    jz _good ; if they are equal, go to _good

    _bad: invoke StdOut, addr BadText

    jmp _quit

    _good: invoke StdOut, addr GoodText

    _quit: invoke ExitProcess, 0

    end start

    注意:“;”符号表示注释。所有跟在它后面的字符都不会被编译。把提示和注意点放在注释中是个好主意,它能让你的代码易读。

    第四章

     

     

     

     

     


    IV. 窗体程序基础

    窗体程序通常由一个或几个窗体组成。因此,做为windows程序员至少要懂得怎么创建一个简单的窗体。很不幸,它不是那么容易的事,但是本教程会指导你怎么去做。

    预备知识

    在编写窗体程序前我们还要讨论几个主题。让我们花点时间复习一下预备知识。

    MASM有几个让汇编编程变得非常容易的宏。我们已经接触到’invoke’,它简单地调用一个函数。下面列出其他几种,之前在你用高级语言编程时它们的用法是很明显的。

    o .if, .else, .endif

    o .while, .break, .endw

    过程

    与高级语言类似,MASM让你定义各种过程使得你的代码易于阅读。它们的格式如下所示:

    <name> proc <var1>:<var1 type>, <var2>:<var2 type>, ...

    <function code>

    ret

    <name> endp

    返回值保存在eax寄存器里,这个过程用下面格式来调用

    invoke <name>, param1, param2, ...

    返回值可以用下面指令来获取

    mov RetVal, eax

    变量

    变量被分配在内存中的,并用来存储你的数据。在没有足够的寄存器可用的情况下,变量是非常有用的。变量有两种类型全局变量和局部变量。如果全局变量已被初始化,它们被置于.data块;如果它们没被初始化的话,就被置于.data?块。还有,如果全局变量被初始化并且不会被改变的话,它们就被置于.const块。声明全局变量的格式如下:

    <name> <type> <value, or ? if uninitialized>

    局部变量是被放于过程内部的,暂时保存,供过程内部使用。它们在创建时不能被初始化。格式如下:

    local <name>:<type>

    有几种变量类型以后将会遇到。其中有几种常见,比如’byte’,’word’ (4 bytes),’dword’(8 bytes)。还有更多,但是它们常常与这三种类型中的一种是相同的,只不过名称不同。


    一个简单的窗体程序

    窗体程序有两个主要的部分。第一部分是WinMain,它创建窗体还包含叫实现消息循环的代码。“消息循环”监视消息并分派消息。第二部分是过程返回WndProc,它是接收消息的,这部分处理你的鼠标事件及刷新窗口等。

    .386

    .model flat, stdcall

    option casemap :none

    include /masm32/include/windows.inc

    include /masm32/include/user32.inc

    include /masm32/include/kernel32.inc

    includelib /masm32/lib/user32.lib

    includelib /masm32/lib/kernel32.lib

    以上是我们通常必需的

    WinMain proto :DWORD, :DWORD, :DWORD, :DWORD

    This is a function prototype. It let's us call the WinMain function later in the program.

    It can be compared to a C/C++ function declaration.

    这是函数原型。在稍后的程序里我们称它为WinMain函数。

    .data

    ClassName db "WinClass", 0

    AppName db "Simple Window", 0

    我们声明我们的字符变量

    .data?

    hInstance HINSTANCE ?

    变量hInstance保存模块实例的句柄,以便与窗体相关联。稍后我们将把它传递到CreateWindow函数中。

    .code

    start:

    invoke GetModuleHandle, NULL

    mov hInstance, eax

    invoke WinMain, hInstance, NULL, NULL, 0

    invoke ExitProcess, eax

    获取模块句柄并把它保存到变量hInstance中。接着调用WinMain函,而已退出。WinMain是这个程序的核心,所以我们将深入研究它。

    注意:从这点来看,我们假设你能够从MSDN中查找windows函数。它有函数参数,返回值,还有其它你必须了解的信息。你可以在附加资源这个章节里获取关于MSDN的信息。

     

     

     


    WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR,

    CmdShow:DWORD

    local wc:WNDCLASSEX

    local msg:MSG

    local hwnd:HWND

    这是WinMain函数的开头部分。我们声明了三个局部变量:wcmsg,,还有hwndWc保存我们创建的窗口类,窗体类是一个创建窗体的模板。Msg保存消息循环中返的消息。Hwnd保存我们窗本的句柄。

    mov wc.cbSize, SIZEOF WNDCLASSEX

    mov wc.style, CS_HREDRAW or CS_VREDRAW

    mov wc.lpfnWndProc, offset WndProc

    mov wc.cbClsExtra, NULL

    mov wc.cbWndExtra, NULL

    注意:在窗体程序中,’or’操作运算符常常用来联合参数中的标志。

    push hInstance

    pop wc.hInstance

    mov wc.hbrBackground, COLOR_WINDOW+1

    mov wc.lpszMenuName, NULL

    mov wc.lpszClassName, offset ClassName

    invoke LoadIcon, NULL, IDI_APPLICATION

    mov wc.hIcon, eax

    mov wc.hIconSm, eax

    invoke LoadCursor, NULL, IDC_ARROW

    mov wc.hCursor, eax

    invoke RegisterClassEx, addr wc

    这些是填充我们先前声明的wc结构。然后以wc为参数调用RegisterClassEx。至于更多关于wc的每个成员的信息,请在MSDN中查找WNDCLASSEX结构的资料。

    invoke CreateWindowEx, 0, addr ClassName, addr AppName, WS_OVERLAPPEDWINDOW

    or WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,

    NULL, hInst, NULL

    mov hwnd, eax

    调用CreateWindowEx函数创建窗体。其中有很多参数被传递进去来表明怎么创建窗体。窗体的句柄会返回并保存到变量hwnd中。

    .while TRUE

    invoke GetMessage, addr msg, NULL, 0, 0

    .break .if (!eax)

    invoke TranslateMessage, addr msg

    invoke DispatchMessage, addr msg

    .endw

    这个while循环也就是先前提到的消息循环。当一个输入事件发生,系统会传递这个事件到一个消息里,并把消息放进程序的消息队列中去。GetMessage取回这些消息并保存进变量msg里。TranslateMessage把键盘消息转换成字符消息。最后,DispatchMessage把这些消息发送到WndProc函数里。在WndProc函数中,这些消息将会被处理。

    mov eax, msg.wParam

    ret

    WinMain endp

    返回值保存进msg.wParam,WinMain函数结束。

    WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

    .if uMsg == WM_DESTROY

    invoke PostQuitMessage, 0

    .else

    invoke DefWindowProc, hWnd, uMsg, wParam, lParam

    ret

    .endif

    xor eax, eax

    ret

    WndProc endp

    WndProc函数是处理消息的地方。唯一一个一定要处理的消息是WM_DESTROY,它通过调用PostQuitMessage来退出程序。如果有其它你要处理的事件,你可以在这里把它们加进来。普通要处理的消息是WM_CREATE(当创建窗体时),WM_PAINT (当窗体必须重画时), 还有WM_CLOSE (关闭窗体时)。其它没有处理的消息被传递给DefWindowProc函数对消息进行默认处理

    end start

    就这些了。你已经了解了怎么去创建一个窗体!


     

    第五章

    IV. 深入汇编和系统

    下面有一些资料来扩展你关于汇编以及系统编程方面的知识:字符串操作,文件处理,还有系统窗体的控制。

    字符串操作

    字符串,数组都是程序中的基本部分。如果你想显示文本或者请求使用者输入,它们就用得了。它们使用到了如下的寄存器:esi,edi,ecx,eflag中的方向控制标志。方向控制标志是指定移动字符串时的方向。一些常见的字符串操作指令是movsb, cmpsb, stasb, and stosb.为了操作字符串,你可以在字符串控制指令中使用某些rep?的形式。下面是在串操作指令中可以使用到rep?前缀

     

    前缀

    串操作指令

    描述

    rep

    movsb

    复制字符串

    repe

    cmpsb

    比较字符串

    repne

    scasb

    扫描字符串中一个字符

    rep

    stosb

    保存一个字符到字符串中

    下面给个复制字符串的例子

    cld ; sets the direction flag to forward

    mov esi, source ; move the source address in to esi

    mov edi, dest ; move the destination address in to edi

    mov ecx, length ; move the length to copy in to ecx

    rep movsb ; copy length bytes from esi to edi

    文件管理

    在旧的DOS系统世界时,文件是通过使用中断进行操作的。在windows系统里,我们通过使用系统函数访问文件。其中可供我们使用的4种函数是:

    CreateFile 创建或打开一个文件,并返回它的句柄

    ReadFile 从文件中读取数据

    WriteFile 写数据到文件里

    CloseHandle 关闭你用CreateFile函数得到的句柄
    存储

    为了读取文件内容,我们必须分配一些内存来存储数据。内存可以如你所愿地被分配,锁定,但是最后记得解锁和释放。做这些工作的函数是GlobalAlloc, GlobalLock, GlobalUnlock, 还有GlobalFree。相当容易,呵呵!

    程序例子

    这个程序读取"c:/test.txt"的内容,并通过一个消息框输出。

    .386

    .model flat, stdcall

    option casemap :none

    include /masm32/include/windows.inc

    include /masm32/include/user32.inc

    include /masm32/include/kernel32.inc

    includelib /masm32/lib/user32.lib

    includelib /masm32/lib/kernel32.lib

    一些通常的包含文件

    .data

    FileName db "c:/test.txt", 0

    .data?

    hFile HANDLE ?

    hMemory HANDLE ?

    pMemory DWORD ?

    ReadSize DWORD ?

    我们定义字符串,还声明了四个将会用到的变量

    .const

    MEMORYSIZE equ 65535

    这是说明分配多大的内存,这样有足够的空间保存我们的文件

    .code

    start:

    invoke CreateFile, addr FileName, GENERIC_READ, FILE_SHARE_READ,

    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL

    mov hFile, eax

    调用CreateFile函数并保存文件句柄到hFile变量。通常,放置一个'h'在句柄之前,而放置'p'在指针之前

    invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, MEMORYSIZE

    mov hMemory, eax

    invoke GlobalLock, hMemory

    mov pMemory, eax

    分配并锁定我们的内存

    invoke ReadFile, hFile, pMemory, MEMORYSIZE-1, addr ReadSize, NULL

    invoke MessageBox, NULL, pMemory, addr FileName, MB_OK

    这些行是读文件到内存中并输出其内容

    invoke GlobalUnlock, pMemory

    invoke GlobalFree, hMemory

    invoke CloseHandle, hFile

    invoke ExitProcess, NULL

    end start

    可别忘清除工作啊
    控制

    一旦创建了一个窗体程序,我们就会想在上面放置一些按钮还有文件框在上面。幸运地,这是容易的事!它的语法非常类似于创建一个窗体,除此外,我们不必调用RegisterClassEx,因为我们的类将为我们预先定义了。为了做到这些,从第4章内容那里编辑WndProc函数来响应WM_CREATE消息

    .elseif uMsg == WM_CREATE

    invoke CreateWindowEx, NULL, addr ButtonClassName, addr ButtonText, WS_CHILD

    or WS_VISIBLE or BS_DEFPUSHBUTTON, 10, 50, 80, 30, hWnd, ButtonID, hInstance, NULL

    mov hButton, eax

    invoke CreateWindowEx, WS_EX_CLIENTEDGE, addr EditClassName, NULL, WS_CHILD

    or WS_VISIBLE, 10, 10, 100, 20, hWnd, EditID, hInstance, NULL

    mov hEdit, eax

    .data块,你还要增加几个变量。定义EditClassName为"edit",ButtonClassName 为"button"。还有,你要定义EditID 和ButtonID为常量。它们的值是什么并没关系,只要它们在其它控制里不出现相同的ID。此外,你不能对变量hEdit和hButton进行初始化,因为它们都是句柄类型。最后,ButtonText必须赋值为字符串,它将显示在按钮上。现在我们还想知道按钮是什么时候被按下的。这可以通过监视WM_COMMAND消息获知,一个如果按下按钮将会发送的消息。

    .elseif uMsg == WM_COMMAND

    mov eax, wParam

    .if ax == ButtonID

    shr eax, 16

    wParam参数包含了有关消息的信息。我们可以检查它是否是那个按钮发送的消息,因为既然我们不想处理其他控制的消息。Shr是右移位操作指令,它把wParam右移16位。这是一种存取32位寄存器的高16位好方法,这样我们通过访问ax就可以很容易做到了。

    .if ax == BN_CLICKED

    <code for what happens if the button is pressed>

    .endif

    .endif

    现在我们知道按钮已经被按下,我们可以对其做一些事了。如果有兴趣学习更多的窗体知识,看一下附加资源这章节。它列出了一些不错有关系统常规编程的参考书和网站


    附加资源

    互联网

    http://www.xs4all.nl/~smit/ -有有用的x86汇编编程教程

    http://win32asm.cjb.net/ -有优秀的关于windows汇编编程的教程

    http://board.win32asmcommunity.net/ -.一个很活跃的讨论关于windows汇编编程的在线论坛

    书籍

    Programming Windows, 第四版,Charles Petzold著作,是一本出色的系统编程书。它给出了很多系统编程的代码例子,覆盖了关于系统编程的很大范围的主题。

    Intel Pentium 4 Processors Manuals, 可从http://www.intel.com/design/pentium4/manuals/ 获取到。它是x86汇编编程的完整的参考。

    The Art of Assembly Programming, Randall Hyde所著, 可从

    http://webster.cs.ucr.edu/AoA.html获取到。它是我见过最好的和最全面的的x86汇编编程书中

    MASM32

    在你的/masm32/HELP/目录里。它是一个叫masm32.hlp的文件,包含了MASM32指南。它有所有关于宏,标志,代码优化等资料。这是学习汇编特别是MASM32非常好的参考。

    MSDN

    MSDN通常是Visual Studio自带有的,你也可以从网站http://msdn.microsoft.com/在线游览。它包括了关于Windows的系统函数,常量,及所有能够被想象到资料。

    新闻组

    目前有两个涉及x86汇编的新闻组。它们是comp.lang.asm.x86 alt.lang.asm。两者都有相当高的访问量,拥有很多知识渊博的读者

    IRC

    有一个关于windows汇编编程的IRC(internet relay chat)频道,#win32asm on EFNet [http://www.efnet.org/]

     

     

    展开全文
  • 汇编语言必备工具

    2020-03-08 00:05:18
    开发工具 汇编器 MASM NASM GAS HLA 链接器 调试器 GNU汇编器(GAS) 安装汇编器 安装包(binutils)内容 addr2line 将代码转换到文件名和行号 ar 创建、修改和提取文件包 as 将汇编代码转换成目标文件 c++...

    开发工具

    • 汇编器
      • MASM
      • NASM
      • GAS
      • HLA
    • 链接器
    • 调试器

    GNU汇编器(GAS)

    • 安装汇编器
      • 安装包(binutils)内容

        • addr2line 将代码转换到文件名和行号
        • ar 创建、修改和提取文件包
        • as 将汇编代码转换成目标文件
        • c++filter 过滤c++符号
        • gprof 显示程序的基本信息
        • ld 将目标文件链接成可执行文件
        • nlmconv 将目标代码转换成网络模块可加载格式
        • nm 列举目标文件的符号
        • objcopy 拷贝和转换目标文件
        • objdump 显示目标文件信息
        • ranlib 生成存档文件内容的索引
        • readelf 以elf格式实现目标文件的内容
        • size 显示目标文件或者存档文件的分区大小
        • strings 显示目标文件中的字符信息
        • strip 去掉符号信息
        • winres 编译微软源文件

        检查本机是否安装了binutils包

        • rpm -qa | grep binutils
        • dpkg -l | grep binutil
      • 使用汇编器
        as -o test.o test.s

      • 操作符语法

        • 常数使用前缀$
        • 寄存器使用前缀%
        • 将4存入eax 使用 mov $, %EAX
        • ljmp 标识长跳转
    • 链接器
      ld -o mytest mytest.o
    • GNU编译器
      • 使用gcc
        gcc -o test test.c
        gcc -S test.c
    • GNU 调试器
      • 使用gdb
        gcc -gstabs -o test test.c
        gdb test
    • GNU objdump
      • 使用objdump
        • gcc -c test.c
        • objdump -d test.o
    • GNU 分析程序
      • 使用gprof
        gcc-o demo demo.c -pg
        ./demo
        gprof demo > gprof.txt
    展开全文
  • 在2018这个忙碌的三月份里,我匆匆忙忙地完成了两场三级考试(全国计算机三级:嵌入式系统开发技术(ARM...所以就是集中在半个月的时间里对这“三”门汇编语言进行初探和深究,虽然这个过程比较匆忙,但我感觉收获了...
  • Linux环境汇编语言编程初步——AT&T语法
  • 什么是汇编语言

    万次阅读 多人点赞 2018-11-19 21:21:37
    汇编语言(assembly language)是一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符(Mnemonics)代替机器指令的操作码,用地址符号(Symbol)或标号...
  • 树莓派ARM汇编语言编程十讲(第1讲)

    千次阅读 2020-03-13 14:01:21
    树莓派ARM汇编语言编程十讲 内容简介 树莓派单板机(Raspberry Pi Single Computer)是一种极了不起的产品,用户可以以非常低的成本获得一个Linux环境并带GPIO硬件扩展的迷你计算机系统。新一代树莓派4B还提供了良好的...
  • 汇编语言和高级编程语言区别与联系

    万次阅读 多人点赞 2018-11-21 15:06:13
    C语言是作为一个程序员来说,必须要掌握也是最基础的编程语言。...本文简述了编程语言的发展史,以及汇编语言和高级编程语言的区别和联系。在对比中对编程语言有更深入的理解。 一、编程语言的发展历程 自从...
  • 教材:《汇编语言(第三版)》王爽 著 实验环境: windows7 旗舰版 工具集合:百度云链接: 密码: 8yda(工具资源来源自看雪学院-汇编快速入门) 1. Debug的安装以及配置 工具的可以在上面的链接中下载,详细的...
  • 汇编语言到高级编程语言的演变

    千次阅读 2019-06-06 15:32:33
    新的编程语言在不断诞生,新语言想用更聪明的抽象,让某些方面更容易或更强大或利用新技术和新平台带来的优势,让更多人能快速做出美妙的事情。
  • 8086汇编语言讲座

    千人学习 2018-03-20 10:20:26
    关于8086汇编语言,是与计算机原理相结合的,通过汇编语言可以加深对计算机原理的掌握和理解。 另外汇编语言还是可以干成事的,比如破解,外挂等都会用到它。
  • 汇编语言使用的工具

    千次阅读 2018-05-08 17:54:06
    学习汇编语言,我们就要安装64位的汇编开发环境,这里是win764位汇编开发环境的安装。1.把你的文件复制到电脑盘符。我的在电脑D盘2.点击文件,进去文件夹,双击DOSBox0.74-win32-installer.exe3.点击next4.点击next5...
  • 汇编语言入门:debug调试工具

    千次阅读 2015-05-19 13:25:17
    对于大学生来说,基本都需要学习高级编程语言,相信大多数理工类大学生都知道c++、c语言、Java语言等高级语言,也知道机器语言这个最低级的语言,但是却有很多都不知道汇编语言,或许听过这个名字,却不知道用途等。...
  • 学习汇编语言的时候,不可孤立学习汇编语言,当今时代很少之间用到汇编语言编程,但是使用汇编语言分析问题,还是非常重要的。 对于x86系列汇编语言,结合C语言学习效果会比较好。 结合C语言,使用VS 2017调试模式下...
  • 机器语言、汇编语言(低级语言)、高级语言

    千次阅读 多人点赞 2019-11-10 00:00:57
    编程语言的机器级表示:机器语言、汇编语言、高级语言 ​ 首先下面一张图是C语言、汇编语言以及翻译过的机器语言,大家可以先有个大概的眼熟。 1、机器语言 计算机是不能直接识别我们所编写的C程序或者Java程序的。...
  • 参考书:使用王爽写的《汇编语言》第三版学习工具(win7 x64):DOSBox 0.74、masm.exe、link.exe、debug.exe。 另外需要一款编辑器,用来编辑源程序,推荐sublime text。需要到这里下载支持汇编语法高亮的插件:...
  • 基本概念 MASM:Microsoft汇编程序(俗称MASM)是一种工业软件开发工具,已经由主要的操作系统...MASM32 SDK:MASM32 SDK(简称MASM32)是一个独立的项目,旨在简化有经验的程序员进入汇编语言编程领域的工作。...
  • 计算机底层原理——汇编语言

    千次阅读 多人点赞 2020-08-19 12:51:57
    想要成为高级程序员,我们必须要学会汇编语言汇编语言是非常重要的计算机底层技术,一般用于底层的编写。不懂汇编的程序员算不上一个好的程序员,充其量是一个熟练使用某种语言的工程师,而编程高手一定要研究底层...
  • 摘要:经典的老牌编程语言排名有所提升是本月的普遍现象。...唯二合理的解释就是:首先仅能运行汇编语言的小型设备在数量上日益增长,如今甚至连我们的牙刷或者咖啡机也在运行汇编语言;此外汇编语...
  • 汇编语言

    千次阅读 2016-02-28 10:56:55
    汇编语言(assembly language)是一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符(Mnemonics)代替机器指令的操作码,用地址符号(Symbol)或标号...
  • 我不想夸大或者贬低汇编语言。但我想说,汇编语言改变了20世纪的历史。与前辈相比,我们这一代编程人员足够的幸福,因为我们有各式各样的编程语言,我们可以操作键盘、坐在显示器面前,甚至使用鼠标、语音识别。我们...
  •  高级编程语言的发展历程(一)创始纪  高级编程语言的发展历程(二)虚拟机的前世今生  高级编程语言的发展历程(三)FORTRAN 语言是怎么来的  高级编程语言的发展历程(四)LISP 和 AI 的青梅竹马 A  ...
  • 编程语言只是工具

    千次阅读 2016-11-25 15:54:10
     谈谈最近的心得:编程语言只是工具而已。  事情是这样,最近公司有一个游戏的项目,游戏方卡在了 在线状态异常的bug上。折腾了两周没搞定。于是,只能自己上了。 事先没接触过unity 没接触过C#, 前后花费 1小时...
  • c语言主函数名是什么?...python语言不是汇编语言。python是高级语言。Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。汇编语言(assembly language)...
  • 汇编语言课程主页

    千次阅读 多人点赞 2017-02-23 14:49:58
    职业中不指望自己的工具袋中备一把名叫“汇编”的榔头的同学,借着汇编语言,也可以练计算机专业学习的内功。  新培养方案中恢复了这门课,我就想将捣鼓捣鼓这门课程。搞了好多年“计算”的事,早对自己离“计算机...
  • -- 作者 谢恩铭 转载请注明出处 目录 什么是汇编语言 语言层级的区分 汇编语言的特性 学习汇编真的必要吗 汇编怎么学 ...我是2011年学习汇编语言的,那时候编程刚入门不久。 因为专业是嵌入式软件和移动
  • 汇编语言入门

    万次阅读 多人点赞 2017-08-01 20:55:22
    1、汇编需要什么工具和程序,到哪里下载?  目前阶段,汇编程序仅需要两个程序就够了。masm.exe,link.exe。 前者是编译程序,后者是链接程序。另外,为了验证和调试程序,还需要一个程序debug.exe,该程序由...
  • 汇编语言复习(一)

    千次阅读 2020-03-11 17:47:11
    汇编语言: 包含用助记符书写的语句,汇编语言不是可移植的 可移植性: 一种语言,如果它的源程序能够在各种各样的计算机系统中进行编译和运行,那么这种语言是被称为可移植得 。 汇编语言和机器语言是一对一的关系...
  • x86汇编语言简介

    千次阅读 2020-03-07 21:30:44
    汇编语言是最古老的编程语言,它是所有语言中最接近原生机器语言的。它拥有直接访问计算机硬件的特权。 汇编器和链接器 汇编器是一种工具程序,用于将汇编语言符号转换成机器语言的“0101”二进制。链接器同样也是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 58,594
精华内容 23,437
关键字:

汇编语言编程工具