1. 环境配置
  • xp环境配置
    • 拷贝masm615到指定目录
    • 将masm615目录添加进环境 变量
    • 在cmd中输入ml,可识别即配置成功
    • image.png

win10使用dosbox示例:
找到dosbox的目录如下:将masm611拷贝进去
image.png
image.png

然后修改:DOSBox 0.74 Options.bat文件进行配置
将masm611的所在目录挂载到dosbox上
image.png
原来:
image.png
改动:
image.png
若有问题,可以尝试将路径用””包起来
例如:image.png

  • 编译命令
    • ml/c asm文件.asm
    • link asm文件.asm
  • 编译+调试 脚本
    • ml/c %1.asm
    • link %1.obj
    • debug %1.exe
  • 示例:

image.png
image.png
示例代码:

  1. assume cs:code,ds:data,ss:stack
  2. data segment
  3. g_sz db "hello word$" ;用$表示字符串的结束
  4. data ends
  5. stack segment stack
  6. db 128 dup (0)
  7. stack ends
  8. code segment
  9. start:
  10. mov ax,stack
  11. mov ss,ax
  12. mov sp,128
  13. mov ax,data
  14. mov ds,ax
  15. mov ah,9
  16. int 21h
  17. mov ax,4C00H
  18. int 21H
  19. code ends
  20. end start

image.png
image.png

根据上面的编译+调试 脚本,我们新建一个build.txt(修改完改后缀名为.bat)
image.png
然后将其放到dosbox所挂c盘下
image.png

  • 使用build(刚刚创建的.bat文件)

image.png

入口和段

  • 入口
    • 入口点指定使用关键字end,后面跟标号名
    • 入口点可以写在任意段外面,但一般写在文件末尾

image.png

    • 一个程序必须至少有一个段
    • 一个程序中可以定义多个段
    • 段不能嵌套
    • 段可以重命名,重命名的段会被编译到同一块内存中

image.png

  • 注释
    • 汇编中使用分号(;)来标注行注释
    • image.png
  • 常量
    • 整数可以支持多个进制
    • 数值必须以数字开头,如果非数字,前面必须加0
    • 负数前面可以加减号(-)
    • image.png
  • 字符
    • 字符可以用单引号(‘)或双引号(“”)
      • mov byte [bx],’$’
      • mov byte [bx],”$”
      • g_sz db “hello world$”;16位汇编中以美元符结尾
  • 变量
    • 整数可以支持多个类型
    • 整数可以有多个初值,未初始化的值用问好(?)表示
    • 变量一般定义在一个单独的段中

image.png

  1. assume cs:code,ds:data,ss:stack
  2. data segment ;数据段
  3. g_db db 55h
  4. g_dw dw 6644h
  5. g_dd dd 77887788h
  6. g_dq dq 1122334455667788
  7. g_dt dt 11223344556677889900h
  8. g_dw0 dw ? ;是?的话,原来是什么数据就是什么,不初始化
  9. g_sz db "hello world$";16位汇编中以美元符结尾
  10. data ends
  11. stack segment stack
  12. db 128 dup (0)
  13. stack ends
  14. code segment
  15. val db 56h
  16. start:
  17. mov ax,stack
  18. mov ss,ax
  19. mov sp,128
  20. mov ax,4C00H
  21. int 21H
  22. code ends
  23. end start
  • 数组

image.png

  1. data_seg1 segment
  2. g_ary1 dw 5566h,7788h,9966h
  3. g_ary2 dw 10h dup(6666h)
  4. g_ary3 dw 9999,16 dup(7777h),4455h,16 dup(3322h)
  5. data_seg1 ends
  • 属性
    • masm提供了很多伪指令,可以获取变量的大小和地址,称之为变量的属性。
    • image.png
    • ```matlab assume cs:code,ds:data,ss:stack

data segment ;数据段 g_db db 55h g_dw dw 6644h g_dd dd 77887788h g_dq dq 1122334455667788 g_dt dt 11223344556677889900h g_dw0 dw ? ;是?的话,原来是什么数据就是什么,不初始化 data ends

data_seg1 segment g_ary1 dw 5566h,7788h,9966h g_ary2 dw 10h dup(6666h) g_ary3 dw 9999h,16h dup(7777h),4455h,16 dup(3322h) data_seg1 ends

stack segment stack db 128 dup (0) stack ends

code segment val db 56h start:
mov ax,stack mov ss,ax mov sp,128

  1. assume ds:data_seg1 ;要先用assume才能用mov指令访问对应段的标号
  2. mov ax,data_seg1 ;取段的地址
  3. mov ds,ax
  4. mov ax,seg g_ary3 ;取g_ary3的段地址
  5. mov ax,offset g_ary3 ;取g_ary3的偏移地址
  6. lea ax,g_ary3
  7. mov ax,type g_ary2
  8. mov ax,length g_ary2
  9. mov ax,size g_ary2
  10. mov ax,4C00H
  11. int 21H

code ends end start

  1. <a name="WSGda"></a>
  2. ## 堆栈
  3. - stack关键字让程序在被加载的时候指定ss、bp和sp。
  4. - 使用数组为栈设置大小
  5. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12923347/1632757844943-0531bcb8-494a-4270-92bc-0f9ba57d1b61.png#align=left&display=inline&height=279&margin=%5Bobject%20Object%5D&name=image.png&originHeight=279&originWidth=577&size=109455&status=done&style=none&width=577)
  6. - **调用dos功能号**
  7. - 功能号
  8. - dos系统提供的功能(API),通过21号中断来调用
  9. - 每个功能都有一个编号,通过AH指定功能号
  10. - 每个功能的参数查看手册
  11. - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12923347/1632758294216-6a520cbe-f286-4392-9e0f-f57b6caaa128.png#align=left&display=inline&height=186&margin=%5Bobject%20Object%5D&name=image.png&originHeight=186&originWidth=349&size=24880&status=done&style=none&width=349)
  12. 例:显示字符
  13. ```matlab
  14. assume cs:code,ds:data,ss:stack
  15. data segment ;数据段
  16. g_sz db "hello word$" ;用$表示字符串的结束
  17. data ends
  18. stack segment stack
  19. db 128 dup (0)
  20. stack ends
  21. code segment
  22. val db 56h
  23. start:
  24. mov ax,stack
  25. mov ss,ax
  26. mov sp,128
  27. mov dl,"A"
  28. mov ah,2 ;
  29. int 21h
  30. mov ax,4C00H ;程序退出
  31. int 21H
  32. code ends
  33. end start

image.png

  • 键盘输入示例
  1. assume cs:code,ds:data,ss:stack
  2. data segment ;数据段
  3. g_sz db "hello word$" ;用$表示字符串的结束
  4. g_buf db 255,255 dup(00)
  5. data ends
  6. stack segment stack
  7. db 128 dup (0)
  8. stack ends
  9. code segment
  10. val db 56h
  11. start:
  12. mov ax,stack
  13. mov ss,ax
  14. mov sp,128
  15. assume ds:data
  16. mov ax,data
  17. mov ds,ax
  18. mov dx,offset g_buf
  19. mov ah,0ah ;0ah 输入到缓冲区 ds:dx=缓冲区首地址
  20. int 21h
  21. mov ah,1 ;键盘输入并回显
  22. int 21h
  23. mov ah,7 ;键盘输入无回显
  24. int 21h
  25. mov ah,8 ;键盘输入无回显 检测ctrl-break
  26. int 21h
  27. mov dl,"A"
  28. mov ah,2
  29. int 21h
  30. mov ax,4C00H ;程序退出
  31. int 21H
  32. code ends
  33. end start

先演示输入字符串
image.png
image.png

image.png

  1. assume cs:code,ds:data,ss:stack
  2. data segment ;数据段
  3. g_sz db "hello word$" ;用$表示字符串的结束
  4. g_buf db 255,255 dup(00)
  5. data ends
  6. stack segment stack
  7. db 128 dup (0)
  8. stack ends
  9. code segment
  10. mov dx,offset g_sz
  11. mov ah,9
  12. int 21h
  13. val db 56h
  14. start:
  15. mov ax,stack
  16. mov ss,ax
  17. mov sp,128
  18. assume ds:data
  19. mov ax,data
  20. mov ds,ax
  21. mov dx,offset g_buf
  22. mov ah,0ah
  23. int 0
  24. mov ax,4C00H ;程序退出
  25. int 21H
  26. code ends
  27. end start

修图解析,e那里改变中断向量并表所记载的入口地址,改为code segment 的开始位置,有右边dosbox得知段地址为0785,偏移地址为0000
image.png
修改后查看一下
image.png
结果如下:
image.png

作业

4、 从键盘读入任意字符串(不超过255),并输出字符串长度和字符串内容
5、 从键盘读入任意字符串(不超过255),以第一个字母为文件名,将字符串存入文件。
6、 从键盘读入文件名,打开文件(不超过255),显示文件内容
8、 从键盘读入文件名,打开文件(不超过255),输出文件中字符的个数。

  • 5 ```matlab data segment file db ‘?.txt’,0 buf db 100,?,100 dup(?) bufstr db 100,?,100 dup(‘$’) ;键盘输入会往后偏移两位 fh dw ?

error_msg db 0dh,0ah,’error!’,’$’ writer_msg db 0dh,0ah,’open file !input text:’,0ah,’$’ success_msg db 0dh,0ah,’done!’,’$’ data ends

stack segment stack dw 20h dup(?) top label word stack ends

code segment assume ds:data,cs:code,ss:stack p proc far

  1. mov ax,data
  2. mov ds,ax
  3. mov ax,stack
  4. mov ss,ax
  5. lea sp,top
  6. ;输入字符串,取第一个字母为文件名
  7. lea dx,bufstr
  8. mov ah,0ah ;键盘输入字符串到缓冲区
  9. int 21h
  10. mov bl,[bufstr+2]
  11. mov [file],bl
  12. ;
  13. lea dx,file ;文件名
  14. mov cx,0
  15. mov ah,3ch ;创建文件
  16. int 21h
  17. jc error

;================================================================= writer: mov fh,ax;save the code of file lea dx,writer_msg ;显示开始写字符 mov ah,09h int 21h

  1. lea dx,buf
  2. mov ah,0ah ;键盘输入字符串到缓冲区
  3. int 21h
  4. lea si,buf ;
  5. inc si
  6. xor ch,ch
  7. mov cl,[si];1
  8. inc si
  9. mov dx,si;2
  10. mov bx,fh;3
  11. mov ah,40h
  12. int 21h
  13. jc error

;================================================================= success: lea dx,success_msg mov ah,09h int 21h jmp exit
;================================================================= error: mov cx,16 mov bx,ax l1: rol bx,1 mov dl,bl and dl,1 add dl,30h mov ah,02h int 21h loop l1

  1. lea dx,error
  2. mov ah,09h
  3. int 21h

exit: mov ah,4ch int 21h

  1. p endp

code ends end p

  1. - 6
  2. ```matlab
  3. data segment
  4. FileNameFuf db 100,?,100 dup(0)
  5. TheFile db 100 dup(0)
  6. file db 'test.txt',0
  7. buf db 100 dup(?)
  8. fh dw ?
  9. error_msg db 0dh,0ah,'error!','$'
  10. success_msg db 0dh,0ah,'done!','$'
  11. data ends
  12. stack segment stack
  13. dw 20h dup(?)
  14. top label word
  15. stack ends
  16. code segment
  17. assume ds:data,cs:code,ss:stack
  18. p proc far
  19. mov ax,data
  20. mov ds,ax
  21. mov ax,stack
  22. mov ss,ax
  23. lea sp,top
  24. ;输入文件名
  25. lea dx,FileNameFuf
  26. mov ah,0ah ;键盘输入字符串到缓冲区
  27. int 21h
  28. xor cx,cx
  29. xor al,al
  30. copy:
  31. lea bx,FileNameFuf
  32. add bx,2
  33. add bx,cx
  34. mov al,[bx]
  35. cmp al,0dh
  36. je endcopy
  37. mov si,cx
  38. lea bx,TheFile
  39. mov ds:[bx+si],al
  40. cmp cx,100
  41. je endcopy
  42. inc cx
  43. jmp copy
  44. endcopy:
  45. ;
  46. lea dx,file
  47. ;open file
  48. lea dx,TheFile
  49. mov al,0
  50. mov ah,3dh
  51. int 21h
  52. jc error
  53. mov fh,ax
  54. ;read file
  55. lea dx,buf
  56. mov cx,100
  57. mov bx,fh
  58. mov ah,3fh
  59. int 21h
  60. jc error
  61. ; mov cx,ax
  62. ; lea si,buf
  63. ;l1: mov dl,[si]
  64. ; inc si
  65. ; mov ah,02h
  66. ; int 21h
  67. ; loop l1
  68. lea dx,buf ;显示开始写字符
  69. mov ah,09h
  70. int 21h
  71. jmp exit
  72. error:
  73. lea dx,error_msg
  74. mov ah,09h
  75. int 21h
  76. exit:
  77. mov ah,4ch
  78. int 21h
  79. p endp
  80. code ends
  81. end p