WEB开发网
开发学院软件开发C++ 汇编语言的高级语言特性 阅读

汇编语言的高级语言特性

 2008-03-08 11:06:01 来源:WEB开发网   
核心提示: 现在写汇编语言,就象写结构化的高级语言一样,汇编语言的高级语言特性,非常的方便,不信?你看看下面写的小程序就知道啦,其内动作复杂,小弟写不出来 :~~( 请写过MASM 5.x的人自行体会那种复杂的古老方式,没有程序跳转,完全的结构化设计
   现在写汇编语言,就象写结构化的高级语言一样,非常的方便。不信?你看看下面写的小程序就知道啦,没有程序跳转,完全的结构化设计。最后还附有 Glow Glove 总结的小篇文章,供大家学习参考。

;-------------------------------------------------------
;例:计算一个数据的阶乘
;若结果较小,可放在 EAX 寄存器
;若结果较小,可放在 EDX:EAX 寄存器
;文件名:7.asm

    .386
    .model flat,stdcall
    option casemap:none


include windows.inc

include masm32.inc
include kernel32.inc
include user32.inc

includelib masm32.lib
includelib kernel32.lib
includelib user32.lib


    .data?
CharOut db 100 dup(?)

    .code

OutEdxEax PROTO :DWord   ;将EDX:EAX中的数据转换成十进制输出字符串形式!

OutEdxEax proc lpString   ;比如:EDX=0,EAX=01234567H,则转换后的字符串为:
                  -> '19088743',0
    mov edi,lpString  ;指向存放结果的地址
    mov esi,lpString

    mov ecx,10     ;转换成十进制
    .while eax!=0 || edx!=0
      push eax  
      mov eax,edx
      xor edx,edx
      div ecx
      mov ebx,eax
      pop eax
      div ecx
      add dl,'0'   
      mov [edi],dl  ;存放结果
      inc edi
      mov edx,ebx
    .endw

    mov BYTE ptr [edi],0;字符串以0为结尾
    dec edi

    .while edi>esi   ;结果前变后,后变前!

      mov al,[esi]
      xchg al,[edi]
      mov [esi],al
      inc esi
      dec edi
    .endw
    ret
OutEdxEax  endp

start:     ;程序开始
  xor eax,eax ;存放结果的寄存器EDX:EAX=1
  xor edx,edx
  inc eax
  mov ecx,20 ;计算20的阶乘。不能大于20,否则会溢出,结果将不再正确!
  .while ecx>0
    .if edx==0 ;结果在EAX中
      mul ecx
    .else    ;结果在EDX:EAX中
      push edx
      mul ecx
      pop ebx
      push eax
      push edx
      mov eax,ecx
      mul ebx
      pop edx
      add edx,eax
      pop eax
    .endif
    dec ecx
  .endw

  .if edx==0     ;结果在EAX中
    invoke dw2a,eax,addr CharOut
  .else        ;结果在EDX:EAX中
    invoke OutEdxEax,addr CharOut  ;用我们自己的程序转换!
  .endif

  invoke StdOut,addr CharOut ;控制台输出结果
  invoke ExitProcess,NULL   ;结束程序
  end start
----------------------------------------------------------------
生成7.exe的具体操作过程

D:\MASM7>ml /coff /I include 7.asm /link /subsystem:console /libpath:lib
Microsoft (R) Macro Assembler Version 6.14.8444

Copyright (C) Microsoft Corp 1981-1997. All rights reserved.

Assembling: 7.asm
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/subsystem:console /libpath:lib
"7.obj"
"/OUT:7.exe"

D:\MASM7>7
2432902008176640000
D:\MASM7>_
---------------------------------------------------------------------
用W32dasm反编译后的结果,大家可看看“汇编语言”是怎样翻译成“机器语言”的。

Program Entry Point = 00401042 (7.exe File Offset:00001642)

:00401000 55           push ebp
:00401001 8BEC          mov ebp, esp
:00401003 8B7D08         mov edi, dword ptr [ebp+08]
:00401006 8B7508         mov esi, dword ptr [ebp+08]
:00401009 B90A000000       mov ecx, 0000000A
:0040100E EB14          jmp 00401024

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401026(C), :0040102A(C)
|
:00401010 50           push eax
:00401011 8BC2          mov eax, edx
:00401013 33D2          xor edx, edx
:00401015 F7F1          div ecx
:00401017 8BD8          mov ebx, eax
:00401019 58           pop eax
:0040101A F7F1          div ecx
:0040101C 80C230         add dl, 30
:0040101F 8817          mov byte ptr [edi], dl
:00401021 47           inc edi

:00401022 8BD3          mov edx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040100E(U)
|
:00401024 0BC0          or eax, eax
:00401026 75E8          jne 00401010
:00401028 0BD2          or edx, edx
:0040102A 75E4          jne 00401010
:0040102C C60700         mov byte ptr [edi], 00
:0040102F 4F           dec edi
:00401030 EB08          jmp 0040103A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040103C(C)
|
:00401032 8A06          mov al, byte ptr [esi]
:00401034 8607          xchg byte ptr [edi], al
:00401036 8806          mov byte ptr [esi], al
:00401038 46           inc esi
:00401039 4F           dec edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401030(U)
|
:0040103A 3BFE          cmp edi, esi
:0040103C 77F4          ja 00401032
:0040103E C9           leave
:0040103F C20400         ret 0004


//******************** Program Entry Point ********
:00401042 33C0          xor eax, eax

:00401044 33D2          xor edx, edx
:00401046 40           inc eax
:00401047 B914000000       mov ecx, 00000014
:0040104C EB17          jmp 00401065

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401068(C)
|
:0040104E 0BD2          or edx, edx
:00401050 7504          jne 00401056
:00401052 F7E1          mul ecx
:00401054 EB0E          jmp 00401064

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401050(C)
|
:00401056 52           push edx
:00401057 F7E1          mul ecx
:00401059 5B           pop ebx
:0040105A 50           push eax
:0040105B 52           push edx
:0040105C 8BC1          mov eax, ecx
:0040105E F7E3          mul ebx
:00401060 5A           pop edx
:00401061 03D0          add edx, eax
:00401063 58           pop eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401054(U)
|
:00401064 49           dec ecx


* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040104C(U)
|
:00401065 83F900         cmp ecx, 00000000
:00401068 77E4          ja 0040104E
:0040106A 0BD2          or edx, edx
:0040106C 750D          jne 0040107B
:0040106E 6804304000       push 00403004
:00401073 50           push eax
:00401074 E81F000000       call 00401098
:00401079 EB0A          jmp 00401085

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040106C(C)
|
:0040107B 6804304000       push 00403004
:00401080 E87BFFFFFF       call 00401000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401079(U)
|
:00401085 6804304000       push 00403004
:0040108A E825000000       call 004010B4
:0040108F 6A00          push 00000000

* Reference To: KERNEL32.ExitProcess, Ord:0075h
                 |
:00401091 E88E000000       Call 00401124
:00401096 CC           int 03
:00401097 CC           int 03

* Referenced by a CALL at Address:
|:00401074 
|
:00401098 55           push ebp
:00401099 8BEC          mov ebp, esp

:0040109B FF7508         push [ebp+08]

* Possible StringData Ref from Data Obj ->"%lu"
                 |
:0040109E 6800304000       push 00403000
:004010A3 FF750C         push [ebp+0C]

* Reference To: USER32.wsprintfA, Ord:02A5h
                 |
:004010A6 E88B000000       Call 00401136
:004010AB 83C40C         add esp, 0000000C
:004010AE C9           leave
:004010AF C20800         ret 0008


:004010B2 CC           int 03
:004010B3 CC           int 03

* Referenced by a CALL at Address:
|:0040108A 
|
:004010B4 55           push ebp
:004010B5 8BEC          mov ebp, esp
:004010B7 83C4F4         add esp, FFFFFFF4
:004010BA 6AF5          push FFFFFFF5

* Reference To: KERNEL32.GetStdHandle, Ord:013Dh
                 |
:004010BC E869000000       Call 0040112A
:004010C1 8945FC         mov dword ptr [ebp-04], eax

:004010C4 FF7508         push [ebp+08]
:004010C7 E820000000       call 004010EC
:004010CC 8945F4         mov dword ptr [ebp-0C], eax
:004010CF 6A00          push 00000000
:004010D1 8D45F8         lea eax, dword ptr [ebp-08]
:004010D4 50           push eax
:004010D5 FF75F4         push [ebp-0C]
:004010D8 FF7508         push [ebp+08]
:004010DB FF75FC         push [ebp-04]

* Reference To: KERNEL32.WriteFile, Ord:02B9h
                 |
:004010DE E84D000000       Call 00401130
:004010E3 8B45F8         mov eax, dword ptr [ebp-08]
:004010E6 C9           leave
:004010E7 C20400         ret 0004


:004010EA CC           int 03
:004010EB CC           int 03

* Referenced by a CALL at Address:
|:004010C7 
|
:004010EC 55           push ebp
:004010ED 8BEC          mov ebp, esp
:004010EF 53           push ebx
:004010F0 8B4508         mov eax, dword ptr [ebp+08]

:004010F3 8D5003         lea edx, dword ptr [eax+03]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040110B(C)
|
:004010F6 8B18          mov ebx, dword ptr [eax]
:004010F8 83C004         add eax, 00000004
:004010FB 8D8BFFFEFEFE      lea ecx, dword ptr [ebx+FEFEFEFF]
:00401101 F7D3          not ebx
:00401103 23CB          and ecx, ebx
:00401105 81E180808080      and ecx, 80808080
:0040110B 74E9          je 004010F6
:0040110D F7C180800000      test ecx, 00008080
:00401113 7506          jne 0040111B
:00401115 C1E910         shr ecx, 10
:00401118 83C002         add eax, 00000002

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401113(C)
|
:0040111B D0E1          shl cl, 1
:0040111D 1BC2          sbb eax, edx
:0040111F 5B           pop ebx
:00401120 C9           leave
:00401121 C20400         ret 0004

* Referenced by a CALL at Address:
|:00401091 
|

* Reference To: KERNEL32.ExitProcess, Ord:0075h
                 |
:00401124 FF2508204000      Jmp dword ptr [00402008]


* Referenced by a CALL at Address:
|:004010BC 
|

* Reference To: KERNEL32.GetStdHandle, Ord:013Dh
                 |
:0040112A FF2500204000      Jmp dword ptr [00402000]

* Referenced by a CALL at Address:
|:004010DE 
|

* Reference To: KERNEL32.WriteFile, Ord:02B9h
                 |
:00401130 FF2504204000      Jmp dword ptr [00402004]

* Reference To: USER32.wsprintfA, Ord:02A5h
                 |
:00401136 FF2510204000      Jmp dword ptr [00402010]
:0040113C 00000000000000000000  BYTE 10 DUP(0)

------------------------------------------------------------------
MASM 6.x 新增指令列表: Glow Glove 制 (请体谅小弟辛劳,勿消去)

MASM 6.x 推出以久,但市面上有关之书籍及资料却少得可怜,小弟当初接触
MASM 6.x 时,辛辛劳苦才找出资料的,为了那些後进不用踏著先烈的血迹前
扑後继,特将小弟「翻」出来的东东公布出来。

这些指令都是小弟从书上(厚颜无耻,在老板的白眼下辛劳抄下来的)
及MASM 6.0 之范例程式中翻出来的,若有遗落疏失,请包涵。
请体谅小弟之辛劳,勿将小弟的ID消去。

MASM 6.x与MASM 5.x最大不同,在於6.x 比5.x 更高阶化了(或说更PASCAL化),
其内提供了判定、回圈、模组化副程式等,各种令组合语言使用者望穿秋水之指
令,看完内容,请不要感动的痛哭流涕,或恨他为什麽不早点出来。

运算符号:
  == : 等於    & : 位元测试
  != : 不等於   ! : 否 NOT
  > : 大於    && : 且 AND
  < : 小於    || : 或 OR

辅助运算符号:
  ZERO?   : ZERO ZF=1,ZR    !ZERO?   : NOT ZERO ZF=0,NZ
  CARRY?  : CARRY CF=1,CY    !CARRY?  : NOT CARRY CF=0,NC
  OVERFLOW? : OVERFLOW,OV     !OVERFLOW? : NOT OVERFLOW,NV
  SIGN?   : NEGATIVE,NG     !SIGN?   : PLUS,PL
  PARITY?  : PARITY EVEN,PE   !PARITY?  : PARITY ODD,PO


Examples:
  .IF AX == 1        .REPEAT
  .IF ZERO?         .UNTIL ZERO?
  .IF !(AX & 0Fh)
  .IF AL=ESC || AL=CR
  看到这些指令了吗? 是不是似曾相识,期待以久了。

判定式:
  .IF
     .
  .ELSEIF
     .
  .ELSE
     .
  .ENDIF

  .ELSEIF 及.ELSE 为非必要之动作,写过高阶语言的应该不难了解才对!

回圈指令:
  (1) 前测式:
    .WHILE
       .
       .
    .ENDW
    当条件成立,即执行回圈内,否则执行回圈後之动作

  (2) 後测式:
   1. .REPEAT
       .
       .
     .UNTIL
    or
   2. .REPEAT
       .
       .
     .UNTILCXZ

   1. 回圈一直到条件成立即停止回圈
   2. 同1 ,但加上判定CX是否为0 (OR的关系,即条件为真或CX==0)

辅助指令:
  .BREAK
  .COUNTINE

  配合上述回圈指令运用
  .BREAK  可中止回圈
  .COUNTINE 可跳至回圈开头
  可在其後加上叙述,叙述成立才动作

嗯! 愈看愈像PASCAL了

Examples:

  .WHILE AX==1 || !ZERO?   .REPEAT
      .             .
  .ENDW           .UNTIL (AX & 1)

  .REPEAT
      .

    .BREAK .IF ZERO?
      .
    .COUNTINE
      .
  .UNTILCXZ (DX == 0)

引申:
  上述之判定式及回圈,其实就是CMP XX,YY
                Jxx xxxx,LOOPxx xxxx
                之组合。

  其内动作复杂,小弟写不出来 :~~( 请写过MASM 5.x的人自行
  体会那种复杂的古老方式。

以上内容为:MASM 6.x 新增指令列表: Glow Glove 制 (请体谅小弟辛劳,勿消去)

Tags:汇编语言 高级

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接