表达式

表达式中的求值是在程序链接时完成的,所以表达式中的各值必须是在汇编或链接期就能确定,也就是说不能将寄存器或者变量运用于表达式。

算术表达式

ASM16-10-宏汇编语法 - 图1

逻辑运算

逻辑运算即位运算,逻辑运算符与对应的指令助记符单词是相同的,当它们出现在操作码部分时是指令,出现在操作数时是逻辑运算符。 ASM16-10-宏汇编语法 - 图2```matlab mov ax,5566h and 6655h mov ax,7788h or 8877h mov ax,not 5566h mov ax,5566h xor 7788h

  1. <a name="8E1jy"></a>
  2. ### 标号
  3. - @@是匿名标号
  4. - @b向上查找最近的@@,b是back
  5. - @f向下查找最近的@@,f是front
  6. ```matlab
  7. @@:
  8. mov ax,5566h and 6655
  9. @@:
  10. mov ax,7788h or 8877h
  11. jmp @b ;跳转到第三行
  12. jmp @f ;跳转到第8行
  13. @@:
  14. mov ax,not 5566h
  15. @@:
  16. mov ax,5566h xor 7788h

调整偏移量指令ORG

  • 格式ORG偏移值
  • 此指令后的下一个变量或指令从偏移开始存放 ```matlab data_seg segment g_buf dw 10h dup(0) org 20h g_w dw 65h ;段偏移20h开始存放 org 4 g_20 dw 655h ;会与buff的第四个字节开始的数据重复 data_seg ends

CODE segment START: org 100h mov ax,5566h and 6655h ;此指令从 代码段偏移100h开始存放

mov ax,4c00h int 21h CODE ends end START

  1. <a name="BcTkr"></a>
  2. ### 当前地址伪指令
  3. - $伪指令代表当前指令或变量的地址
  4. - 可用于
  5. - 可与**ORG**配合使用
  6. ```matlab
  7. data_seg segment
  8. g_buf dw 10h dup(0)
  9. g_len dw $ - offset g_buf; 获取上面g_buf的长度
  10. org $ + 10h ;下一个遍历从当前地址+10h的偏移开始存放
  11. g_w dw 65h
  12. data_seg ends
  13. CODE segment
  14. START:
  15. org 100h
  16. mov ax,5566h and 6655h ;此指令从 代码段偏移100h开始存放
  17. mov ax,$ ;获取本条指令的地址
  18. mov ax,$+4;获取本条指令的地址+4
  19. mov ax,4c00h
  20. int 21h
  21. CODE ends
  22. end START
  • 花指令 ```matlab ;======================================;======================================data segment data segment db 1 g_sz db “hello world”,0 g_wLen dw $ - offset g_sz ;存放g_sz的长度 g_sz2 db “ell”,0 org $+10h g_w dw 5566h g_w2 dw 7788h data ends ;======================================;======================================stack segment stack segment stack dw 20h dup(?) top label word stack ends

;======================================;======================================code segment code segment assume ds:data,cs:code,ss:stack start: ;=========================================INIT mov ax,data mov ds,ax

  1. mov ax,stack
  2. mov ss,ax
  3. lea sp,top

;=========================================code todo LABEL_THIS: mov ax,offset LABEL_THIS mov ax,$

  1. ;===========花指令
  2. jmp $+3
  3. db 0e9h
  4. mov ax,67 ;
  5. ;===========

;=========================================code ends ENDCODE:;程序退出 mov ah,4ch int 21h
;==================================================== code ends end start

  1. <a name="aPRCK"></a>
  2. ### 结构体
  3. ```matlab
  4. 结构体名 struc
  5. ;这里定义结构体成员
  6. 结构体名 ends

局部变量和全局变量使用示例:

  1. ;======================================;======================================stack segment
  2. stack segment stack
  3. dw 20h dup(?)
  4. top label word
  5. stack ends
  6. ;======================================;======================================
  7. Student struc
  8. m_id dw ?
  9. m_sz db 256 dup(?)
  10. Student ends
  11. data_seg segment
  12. g_stu Student <56,"hello world...">
  13. data_seg ends
  14. code_seg segment
  15. Func PROC far c uses bx cx si di src:word,substr00:word
  16. local @stu:Student
  17. mov @stu.m_id,78
  18. lea bx,@stu.m_sz
  19. ;寄存器使用
  20. assume bx:ptr Student ;要明确高数它这个是哪个结构体的指针
  21. lea bx,@stu
  22. mov [bx].m_id,99
  23. assume bx:onthing ;用完之后nothing一下释放
  24. ret
  25. Func ENDP
  26. code_seg ends
  27. ;======================================;======================================code segment
  28. code segment
  29. assume ds:data_seg,cs:code,ss:stack
  30. start:
  31. ;=========================================INIT
  32. mov ax,data_seg
  33. mov ds,ax
  34. mov ax,stack
  35. mov ss,ax
  36. lea sp,top
  37. ;=========================================code todo
  38. mov g_stu.m_id,56
  39. lea bx,g_stu.m_sz
  40. invoke Func,bx,cx
  41. ;=========================================code ends
  42. ENDCODE:;程序退出
  43. mov ah,4ch
  44. int 21h
  45. ;====================================================
  46. code ends
  47. end start

equ语句

  • 不可以重命名
  • 可用于常量和表达式
  • 可用于字符串
  • 可用于指令名,给指令取别名
  • 可用于类型,给类型取别名
  • 可用于操作数

    1. COUNT equ 100h ;后跟数值
    2. SZHELLO equ "hello world"
    3. MOVE equ mov ;后跟助记符
    4. MYWORD equ dw ;后跟类型
    5. BX_CONE eque byte ptr [bx];后跟表达式

    示例2:

    1. MAXBYTE equ 255
    2. VERSION equ "5.261"
    3. MOVE equ mov
    4. GETBX equ byte ptr [bx]
    5. WORDBYPE equ dw
    6. ;定义后,其下面就可以直接使用它们

    =语句

  • 可以被修改

  • 只能用于常数

    1. COUNT2 = 100h ;后跟数值
    2. COUNT2 = 200h;可以再次赋值
    3. mov ax,COUNT2
    4. ;==================
    5. ;函数内
    6. @val1 = -2
    7. @val2 = -4
    8. test00 equ 100
    9. ;下面两条使用局部变量看起来更舒服
    10. mov ax,[bp+@val1]
    11. mov ax,[bp+@val2]
    12. mov ax,test00

    macro语句

  • 格式

    1. 宏名 macro [参数1][参数2]...
    2. 宏体
    3. endm
  • 宏会在使用的地方展开

  • 宏可以带参数
  • 字符串拼接使用&
    1. movm marco op1,op2
    2. push op2
    3. pop op1
    4. endm
    5. shift macro n,reg,d
    6. mov cl,n
    7. ro&d reg,cl
    8. endm
    常用的一些用法示例: ```matlab ExitProcess macro mov ax,4c00h int 21h endm movm macro arg1,arg2 push arg2 pop arg1 endm

shift4 MACRO reg,der mov cl,4 ro&der reg,cl ENDM ;======================================;======================================stack segment stack segment stack dw 20h dup(?) top label word stack ends ;======================================;======================================

data_seg segment g_dw1 dw 5566h g_dw2 dw 7788h data_seg ends

code_seg segment Func PROC far c uses bx cx si di src:word,substr00:word

  1. ret

Func ENDP code_seg ends ;======================================;======================================code segment code segment assume ds:data_seg,cs:code,ss:stack start: ;=========================================INIT mov ax,data_seg mov ds,ax

  1. mov ax,stack
  2. mov ss,ax
  3. lea sp,top

;=========================================code todo movm g_dw1,g_dw2

  1. shift4 ax,r
  2. shift4 bx,l

;=========================================code ends ENDCODE:;程序退出 ExitProcess ;==================================================== code ends end start

  1. 更多宏语法可以查找老师之前给的资料->汇编中文手册
  2. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12923347/1633014135913-bf41b4c5-3a49-4afe-b090-3bfd80229472.png#align=left&display=inline&height=476&margin=%5Bobject%20Object%5D&name=image.png&originHeight=476&originWidth=634&size=427752&status=done&style=none&width=634)
  3. <a name="hII9n"></a>
  4. ## 多文件编译
  5. 源文件
  6. - 源文件后缀名为asm
  7. - 每个源文件末尾需要有end
  8. 头文件
  9. - 汇编头文件后缀名为inc
  10. - 头文件包含include xxx.inc
  11. - 头文件防重复包含
  12. **示例:**<br />Test.asm
  13. ```matlab
  14. include 2.inc
  15. ExitProcess macro
  16. mov ax,4c00h
  17. int 21h
  18. endm
  19. movm macro arg1,arg2
  20. push arg2
  21. pop arg1
  22. endm
  23. shift4 MACRO reg,der
  24. mov cl,4
  25. ro&der reg,cl
  26. ENDM
  27. ;======================================;======================================stack segment
  28. stack segment stack
  29. dw 1024h dup(?)
  30. top label word
  31. stack ends
  32. ;======================================;======================================
  33. data_seg segment
  34. g_dw1 dw 5566h
  35. g_dw2 dw 7788h
  36. data_seg ends
  37. ;======================================;======================================code segment
  38. code segment
  39. assume ds:data_seg,cs:code,ss:stack
  40. start:
  41. ;=========================================INIT
  42. mov ax,data_seg
  43. mov ds,ax
  44. mov ax,stack
  45. mov ss,ax
  46. lea sp,top
  47. ;=========================================code todo
  48. movm g_dw1,g_dw2
  49. invoke Func,bx,cx
  50. mov ax,g_w2
  51. shift4 ax,r
  52. shift4 bx,l
  53. ;=========================================code ends
  54. ENDCODE:;程序退出
  55. ExitProcess
  56. ;====================================================
  57. code ends
  58. end start

2.inc

  1. ifndef MY_2_INC_XXXXX ;防止重复包含
  2. MY_2_INC_XXXXX equ 0 ;防止重复包含
  3. Func proto far c src:word,substr00:word
  4. extern g_w2:word
  5. endif ;防止重复包含

2.asm

  1. public g_w2 ;去掉g_w2的默认static属性
  2. data segment
  3. g_w2 dw 9999h
  4. data ends
  5. code segment
  6. Func PROC far c uses bx cx si di src:word,substr00:word
  7. .if ax > 0
  8. .endif
  9. ret
  10. Func ENDP
  11. code ends
  12. end

编译连接方法:

  1. ml *.asm
  2. ml test.asm 2.asm
  3. ml /c test.asm 2.asm link test.asm 2.asm

下面是test调用2的函数和使用2的全局变量
image.png
汇编中文手册:用伪指令实现的分支结构
image.png