西电计组II 实验1
创始人
2024-01-31 14:44:16

西电计组II 实验1

文章目录

  • 西电计组II 实验1
    • 8086汇编 IO操作
      • 环境搭建
      • 8086汇编 helloworld
        • assume
        • segment
        • db
      • 编译链接
        • lst
        • map
        • obj
        • exe
        • sym
        • dob
      • int 21H 软件中断
      • 程序设计
        • 要求
        • 全局变量
        • 函数设计
          • putchar
          • getchar
          • print
          • newline
          • input
          • memset
          • exit
          • hex
          • binary
          • circle
        • 程序入口
      • 完整代码

8086汇编 IO操作

环境搭建

win32平台上仍然保留了MS-DOS的解释器,可以模拟16位环境(NTVDM.EXE),但是win64就白搭了

机房里的电脑是win7 32位操作系统,可以在cmd终端上直接运行ms-dos应用程序

但是我自己的win11 64位,尝试终端运行ms-dos程序会报告不兼容.

但是在win64上也有方法,要么是用星研电子IDE(实际上使用的是TASM编译器+dosbox模拟16位dos环境)

要么是建立一个虚拟硬盘,在其前512字节的主引导扇区中写入编译好的机器码,然后用bochs或者vmware等虚拟机软件运行

…方法有的是…

在我的电脑上,采用vscode编写汇编代码+星研IDE编译链接运行

8086汇编 helloworld

要了解8086汇编语言的基本结构,最快的办法是学习如何打印helloworld

assume cs:code,ds:data,ss:mystack
data segmentbuffer db 'Hello World!',10,13,'$'
data ends 
mystack segment stackdb 32 dup(?)
mystack endscode segment
start:mov ax,datamov ds,axlea dx,buffermov ah,9int 21hmov ah,4chint 21h
code ends
end start

在星研IDE中编译连接运行会在屏幕打印helloworld

下面逐条语句分析程序作用

assume

assume cs:code,ds:data,ss:mystack

assume是tasm的伪指令,不会产生任何机器码,其作用是,将段寄存器和我们定义的段关联,以后在ds段中寻址的时候,就是在data中寻址

这既是给程序员看的,也是给tasm编译器看的,但不是给机器看的

即使在这里将ds和data段关联,我们在代码段的一开始还是要lea ax,data然后mov ds,ax,这样设置代码段的指向.只有这样才会生成相关机器代码,机器才会知道ds段在哪

给tasm编译器看,也就是说当使用mov [di],ax这种没有显示指明内存地址的段寄存器时,tasm知道我们实际上在使用data段作为ds段寄存器,然后ds:[di]这样寻址

segment

定义段

tasm要求一个程序必须要有代码段,数据段,堆栈段,即使用不到,不写,会给警告,不给通过编译

定义一个段的写法:

data segment...
data ends mystack segment stack;这里后面的stack是段属性,stack显示指出是一个堆栈段...
mystack ends

db

定义数据,这个数据是会出现在程序中的,要和"常数"区别

类比c语言,db定义的是变量,"常数"是宏

buffer db 'Hello World!',10,13,'$'

标号 db 数据1,数据2,…

其中db是定义字节的意思,意味着后面的数据1,数据2等都视为字节

如果是dw则后面的操作数视为字

编译链接

只需要在星研IDE中傻瓜一样点一下编译链接即可,同目录下加上asm共有7个同名文件

PS C:\Users\Administrator\Desktop\helloworld> ls | findstr "hw"
-a---          2022/11/19     0:01            292 hw.asm
-a---          2022/11/19     0:01             68 hw.dob
-a---          2022/11/19     0:01           1221 hw.exe
-a---          2022/11/19     0:01           1418 hw.lst
-a---          2022/11/19     0:01            383 hw.map
-a---          2022/11/19     0:01            414 hw.obj
-a---          2022/11/19     0:01            222 hw.sym

其中asm自然是源文件

lst

lst也是写给程序员看的,列表列明的程序内容

包括行号,带机器码,带汇编指令

符号表,段信息

Turbo Assembler	 Version 4.1	    11/19/22 00:01:35	    Page 1
hw.asm12				     assume cs:code,ds:data,ss:mystack34	0000			     data segment5	0000  48 65 6C 6C 6F 20	57+	     buffer db 'Hello World!',10,13,'$'6	      6F 72 6C 64 21 0A	0D+7	      248	000F			     data ends9	0000			     mystack segment stack10	0000  20*(??)			     db	32 dup(?)11	0020			     mystack ends1213	0000			     code segment14	0000			     start:15	0000  B8 0000s			     mov ax,data16	0003  8E D8			     mov ds,ax17	0005  BA 0000r			     lea dx,buffer18	0008  B4 09			     mov ah,919	000A  CD 21			     int 21h2021	000C  B4 4C			     mov ah,4ch22	000E  CD 21			     int 21h23	0010			     code ends24				     end start
Turbo Assembler	 Version 4.1	    11/19/22 00:01:35	    Page 2
Symbol TableSymbol Name			  Type	 Value??DATE				  Text	 "11/19/22"
??FILENAME			  Text	 "hw	  "
??TIME				  Text	 "00:01:35"
??VERSION			  Number 040A
@CPU				  Text	 0101H
@CURSEG				  Text	 CODE
@FILENAME			  Text	 HW
@WORDSIZE			  Text	 2
BUFFER				  Byte	 DATA:0000
START				  Near	 CODE:0000Groups & Segments		  Bit Size Align  Combine ClassCODE				  16  0010 Para	  none
DATA				  16  000F Para	  none
MYSTACK				  16  0020 Para	  Stack

map

map文件也是给人看的,包括段的映射信息,段在源文件中的行号,程序入口点的位置

 Start  Stop   Length Name               Class00000H 0000EH 0000FH DATA               00010H 0002FH 00020H MYSTACK            00030H 0003FH 00010H CODE               Line numbers for hw.obj(HW.ASM) segment CODE13 0003:0000    14 0003:0003    15 0003:0005    16 0003:000817 0003:000A    19 0003:000C    20 0003:000E
Program entry point at 0003:0000

obj

coff可重定位目标模块

早期操作系统的目标模块,如今windows上仍在使用obj作为目标模块,但是结构已经发生了变化

编译生成的产物,和其他模块一起链接生成exe

exe

coff可执行目标模块,如今windows上仍在使用exe作为可执行程序,但是结构已经发生了变化

链接的产物,可以在16位环境下直接执行

用010editor等二进制编辑器可以观察其结构

image-20221119004723312

开头就是MZ魔数

sym

推测是符号表文件

image-20221119004836011

dob

可能是dump object的缩写

整个程序翻译成的机器码,包括数据段,代码段,堆栈段

image-20221119005524411

int 21H 软件中断

int 21h是dos系统提供的基本的io操作

调用约定是AH中存放入口参数,如果有其他参数,可能使用DL等寄存器,结果如果有返回值,则通常放到AL寄存器

本次实验要用到的功能具体如下

AH 调 用 参 数
1键盘输入并回显AL=输出字符
2显示单个字符(带Ctrl+Break检查)DL=输出字符光标在字符后面
6显示单个字符(无Ctrl+Break检查)DL=输出字符光标在字符后面
8从键盘上读一个字符AL=字符的ASCII码
9显示字符串DS:DX=串地址,‘$’为结束字符光标跟在串后面
4CH返回DOS系统AL=返回码

程序设计

要求

要求是输入学号姓名,回车后回显学号姓名

然后输入一个字符,打印其ascii码值

全局变量

DSEG SEGMENThelloworld DB 'Hello,World!' ,0DH,0AH,24Hnext_row   DB 0DH,0AH,24H;打印换行使用buffer     DB 0100H dup('$');输入缓冲区STUID      DB 'please input your id >','$';提示输入学生姓名时打印STUNAME    DB 'please input your name >','$'cmdprompt  DB 'please input an alpha to get its ascii code, q to quit >','$';提示输入字符时打印
DSEG ENDS

函数设计

putchar
功能打印一个字符
调用约定al输入该字符

使用入口为2H的int 21软中断打印到屏幕

        ;调用约定:需要打印的字符->al
putchar procpush   dxmov    ah,02hmov    dl,alint    21hpop    dxret
putchar endp
getchar
功能输入一个字符
调用约定al返回该字符
        ;调用约定:输入字符用al返回
getchar proc nearmov    ah,01hmov    al,0int    21Hretn
getchar endp
print
功能打印字符串
调用约定AX存放字符串及地址,打印到碰到$字符结束
        ;调用约定:ax指定一个buffer的基地址,用于获取一个字符串
print proc nearpush   bxpush   cxpush   dxmov    dx,axmov    ah,09Hmov    al,00Hint    21Hpop    dxpop    cxpop    bxret
print endp
newline
功能打印换行
调用约定无参数无返回值
newline proc nearpush   axlea    ax,next_rowcall   printpop    axret
newline endp
input
功能输入字符串
调用约定AX存放缓冲区地址,输入直到回车结束
        ;AX存放目的地址,结束时CX返回输入字符个数
input proc nearpush   BX;     push   cx;     push   di;     push   ax;     MOV    CX, 0ffh;     mov    DI, ax;     mov    al,'$';     REPZ   STOSB;     pop    axMOV    DX,AXMOV    BX,DXMOV    byte ptr DS:[BX], 0ffh;     mov    [DX],BLmov    ah,0ah                        ;将0ah放入ahmov    al,0int    21h                           ;输入字符串功能调用pop    BXret
input endp
memset
功能缓冲区初始化,即c语言的memset函数
调用约定ax存放基地址,cx存放长度,bl存放初始化字符
        ;调用约定:ax存放基地址,cx存放长度,bl存放目标字符
memset proc nearpush   dimov    di,axmemset_circle:cmp    cx,0jz     memset_finimov    ds:[di],blinc    didec    cxjmp    memset_circlememset_fini:  pop    diret
memset endp
exit
功能返回函数,将控制交给调用者
调用约定无参数无返回值
exit proc nearmov    ah,4Chmov    al,0int    21h
exit endp
hex
功能打印一个字节的16进制表示
调用约定ax存放该字节
;16进制打印一个字节
hex PROC nearpush   axpush   dxmov    dx,axmov    ch, 4L1:           mov    cl, 4rol    dx, clmov    al,dland    al,0FHadd    al,30hcmp    al,3ahjl     printitadd    al,7hprintit:      call   putchardec    chjnz    L1pop    dxpop    axret
hex ENDP
binary
功能打印一个字节的2进制表示
调用约定ax存放该字节
        ;二进制形式的输出,入口参数为ax
binary procpush   bx                            ;数据入栈,保留数值push   dxmov    dh,0                          ;用于计数,总共8次binaryagain:  cmp    dh,8je     binaryover                    ;输出结束,到达函数末端rol    ax,1                          ;移动一位mov    bx,ax                         ;数值保留and    ax,0001h                      ;剥离出最后一位mov    dl,al                         ;用于输出add    dl,48mov    ah,2int    21hinc    dh                            ;计数加一mov    ax,bx                         ;数值恢复jmp    binaryagain                   ;再来一次binaryover:   pop    dx                            ;数据出栈,数值还原pop    bxret
binary endp
circle
功能循环输入字符,打印ascii值
调用约定无参数无返回值
circle proc nearrolling:      lea    ax,cmdpromptcall   printlncall   getcharcmp    al,'q'jz     finimov    ah,0call newlinecall   hexcall   newlinejmp    rollingfini:         retncircle endp

程序入口

        BEGIN:        MOV    AX,DSEG;设置DS段寄存器,将DSEG作为数据段MOV    DS,AXcall   newline;遇事不决,换个行先lea    AX,STUIDcall   print;提示输入IDcall   newlinelea    AX,buffermov    cx,0ffhmov    bl,'$'call   memset;初始化缓冲区memset(&buffer,0xFF,'$');lea    AX,buffer;设置输入目标地址call   input;输入call   newlinelea    ax,[buffer+2]call   printcall   newlinelea    AX,STUNAMEcall   printcall   newlinelea    AX,buffermov    cx,0ffhmov    bl,'$'call   memsetlea    AX,buffercall   inputcall   newlinelea    ax,[buffer+2]call   printcall   newlinecall   circlecall   exit;归还控制

完整代码

DSEG SEGMENThelloworld DB 'Hello,World!' ,0DH,0AH,24Hnext_row   DB 0DH,0AH,24Hbuffer     DB 0100H dup('$')STUID      DB 'please input your id >','$'STUNAME    DB 'please input your name >','$'cmdprompt  DB 'please input an alpha to get its ascii code, q to quit >','$'
DSEG ENDSSSEG SEGMENT PARA STACKDW 256 DUP(?)
SSEG ENDSCSEG SEGMENTASSUME CS:CSEG,DS:DSEG;调用约定:需要打印的字符->al
putchar procpush   dxpush   axmov    ah,02hmov    dl,alint    21hpop    axpop    dxret
putchar endp;调用约定:输入字符用al返回
getchar proc nearmov    ah,01hmov    al,0int    21Hretngetchar endp;16进制打印一个字节,调用约定:
hex PROC nearpush   axpush   dxmov    dx,axmov    ch, 4L1:           mov    cl, 4rol    dx, clmov    al,dland    al,0FHadd    al,30hcmp    al,3ahjl     printitadd    al,7hprintit:      call   putchardec    chjnz    L1pop    dxpop    axret
hex ENDP;二进制形式的输出,入口参数为ax
binary procpush   bx                            ;数据入栈,保留数值push   dxmov    dh,0                          ;用于计数,总共16次binaryagain:  cmp    dh,8je     binaryover                    ;输出结束,到达函数末端rol    ax,1                          ;移动一位mov    bx,ax                         ;数值保留and    ax,0001h                      ;剥离出最后一位mov    dl,al                         ;用于输出add    dl,48mov    ah,2int    21hinc    dh                            ;计数加一mov    ax,bx                         ;数值恢复jmp    binaryagain                   ;再来一次binaryover:   pop    dx                            ;数据出栈,数值还原pop    bxret
binary endp;调用约定:ax指定一个buffer的基地址,用于获取一个字符串
print proc nearpush   bxpush   cxpush   dxmov    dx,axmov    ah,09Hmov    al,00Hint    21Hpop    dxpop    cxpop    bxret
print endp;调用约定:ax指定一个buffer的基地址,用于获取一个字符串
println proc nearcall   printmov    al,0Dhcall   putcharmov    al,0DHcall   putcharret
println endpnewline proc nearpush   axlea    ax,next_rowcall   printpop    axret
newline endp;AX存放目的地址,结束时CX返回输入字符个数
input proc nearpush   BX;     push   cx;     push   di;     push   ax;     MOV    CX, 0ffh;     mov    DI, ax;     mov    al,'$';     REPZ   STOSB;     pop    axMOV    DX,AXMOV    BX,DXMOV    byte ptr DS:[BX], 0ffh;     mov    [DX],BLmov    ah,0ah                        ;将0ah放入ahmov    al,0int    21h                           ;输入字符串功能调用pop    BXret
input endpcircle proc nearrolling:      lea    ax,cmdpromptcall   printlncall   getcharcmp    al,'q'jz     finimov    ah,0call newlinecall   hexcall   newlinejmp    rollingfini:         retncircle endp;调用约定:ax存放基地址,cx存放长度,bl存放目标字符
memset proc nearpush   dimov    di,axmemset_circle:cmp    cx,0jz     memset_finimov    ds:[di],blinc    didec    cxjmp    memset_circlememset_fini:  pop    diret
memset endpexit proc nearmov    ah,4Chmov    al,0int    21h
exit endpBEGIN:        MOV    AX,DSEGMOV    DS,AXcall   newlinelea    AX,STUIDcall   printcall   newlinelea    AX,buffermov    cx,0ffhmov    bl,'$'call   memsetlea    AX,buffercall   inputcall   newlinelea    ax,[buffer+2]call   printcall   newlinelea    AX,STUNAMEcall   printcall   newlinelea    AX,buffermov    cx,0ffhmov    bl,'$'call   memsetlea    AX,buffercall   inputcall   newlinelea    ax,[buffer+2]call   printcall   newlinecall   circlecall   exit
CSEG ENDSEND  BEGIN

相关内容

热门资讯

脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
怎么发微博故事 视频号怎么改回... 在被快手、头条、秒拍轮番定义之后,短视频还有哪些新的玩法?当今日头条孵化的抖音迅速蹿红,短视频领域的...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
怎么让男人兴奋 男人抵抗不了女... “男生对女人最初的崇拜,就是一声妈”有些东西分开挺好的,合起来就不行比如一个男人,又苏又大又强,简直...