
通常的应用程序分为3段:代码段、栈段、数据段。
再简化下其实大多数情况是2个段:代码段、数据段(栈段由汇编程序去处理)。
--------------------------------
在复杂的程序中,代码段、数据段都可以是多个的!
--------------------------------
段地址是浮动的(exe是浮动代码可执行文件),由 *** 作系统装载程序时设置。
;----------------------------------
;冒泡排序
;负数显示补码如-1显示65535
;如想增加数据只需在a变量中添加,
;同时长度len要相应的更改
;----------------------------------
data segment
len dw 10
a dw -1,2,100,-100,99,-120,15,46,411,102
b dw 0
data ends
code segment
main proc far
assume cs:code,ds:data
start:
push ds
sub ax,ax
push ax
mov ax,data
mov ds,ax
mov cx,len
dec cx
loop1:
mov di,cx
mov bx,0
loop2:
mov ax,a[bx]
cmp a[bx+2],ax
jge cotinue
xchg ax,a[bx+2]
mov a[bx],ax
cotinue:
add bx,2
loop loop2
mov cx,di
loop loop1
mov si,0
loop3:
mov bx,a[si]
call bini
call crlf
add si,2
mov di,len
add di,len
cmp si,di
jl loop3
ret
main endp
bini proc near
mov cx,10000d
call bin
mov cx,1000d
call bin
mov cx,100d
call bin
mov cx,10d
call bin
mov cx,1d
call bin
ret
bini endp
bin proc near
mov ax,bx
mov dx,0
div cx
mov bx,dx
mov dl,al
add dl,30h
mov ah,02h
int 21h
ret
bin endp
crlf proc near
mov dl,0ah
mov ah,02h
int 21h
mov dl,0dh
mov ah,02h
int 21
ret
crlf endp
code ends
end start
stacksegmentstack\x0d\byte256dup(0)\x0d\stackends\x0d\\x0d\datasegment\x0d\C1dw0;空格数\x0d\C2dw0;数字数\x0d\C3dw0;字母数\x0d\C4dw0;其它字符数\x0d\BUFFdb64,0,64dup();接收输入缓冲区,BUFF[0]存储缓冲区大小,BUFF[1]存储实际输入数,BUFF[2]开始为输入的数据\x0d\SHEXDB'0123456789ABCDEF$'\x0d\MSG1db13,10,'space:$'\x0d\MSG2db13,10,'number:$'\x0d\MSG3db13,10,'alpha:$'\x0d\MSG4db13,10,'other:$'\x0d\MSG5db'inputyourdata,endtoinput#',13,10,'$'\x0d\dataends\x0d\\x0d\codesegment\x0d\assumecs:code,ss:stack,ds:data\x0d\START:\x0d\movax,data\x0d\movds,ax\x0d\movax,stack\x0d\movss,ax\x0d\\x0d\callGetInputData;\x0d\\x0d\callCountInputData;\x0d\\x0d\;输出空格数\x0d\movdx,offsetMSG1\x0d\movax,C1\x0d\callPrintLen\x0d\\x0d\;输出数字数\x0d\movdx,offsetMSG2\x0d\movax,C2\x0d\callPrintLen\x0d\\x0d\;输出字母数\x0d\movdx,offsetMSG3\x0d\movax,C3\x0d\callPrintLen\x0d\\x0d\;输出其他数\x0d\movdx,offsetMSG4\x0d\movax,C4\x0d\callPrintLen\x0d\PROCEXIT:\x0d\;程序退出\x0d\movax,4c00h\x0d\int21h\x0d\\x0d\;打印出长度,长度保存在AX里,DX里存储提示信息地址\x0d\PrintLenprocnear\x0d\pushax\x0d\movah,9h\x0d\int21h\x0d\popax\x0d\\x0d\movcx,4\x0d\PRINTLOOP:\x0d\rolax,1\x0d\rolax,1\x0d\rolax,1\x0d\rolax,1\x0d\pushax\x0d\movdl,al\x0d\anddl,0FH\x0d\movbx,offsetSHEX\x0d\addbl,dl\x0d\movdl,byteptr[bx]\x0d\movah,2\x0d\int21h\x0d\popax\x0d\loopPRINTLOOP\x0d\ret\x0d\PrintLenendp\x0d\\x0d\CountInputDataprocnear\x0d\movch,0\x0d\movcl,byteptr[BUFF+1]\x0d\movsi,offsetBUFF+2\x0d\MYLOOP:\x0d\moval,[si]\x0d\incsi\x0d\\x0d\cmpal,20h;''空格\x0d\jeCCOUNT1\x0d\cmpal,'0';'0'\x0d\jlCCOUNT4\x0d\cmpal,'9';'9'\x0d\jleCCOUNT2\x0d\cmpal,'A';'A'\x0d\jlCCOUNT4\x0d\cmpal,'Z';'Z'\x0d\jleCCOUNT3\x0d\cmpal,'a';'a'\x0d\jlCCOUNT4\x0d\cmpal,'z';'z'\x0d\jleCCOUNT3\x0d\CCOUNT4:\x0d\incC4\x0d\jmpNEXTLOOP\x0d\;空格\x0d\CCOUNT1:\x0d\incC1\x0d\jmpNEXTLOOP\x0d\;数字\x0d\CCOUNT2:\x0d\incC2\x0d\jmpNEXTLOOP\x0d\;字母\x0d\CCOUNT3:\x0d\incC3\x0d\jmpNEXTLOOP\x0d\NEXTLOOP:\x0d\loopMYLOOP\x0d\ret\x0d\CountInputDataendp\x0d\\x0d\;获取输出数据,输入数据保存在BUFF里,个数\x0d\GetInputDataprocnear\x0d\movdx,offsetMSG5\x0d\movah,9h\x0d\int21h\x0d\\x0d\movch,0\x0d\movcl,BUFF\x0d\leabx,BUFF+2;\x0d\INPUTLOOP:\x0d\movah,1\x0d\int21h\x0d\cmpal,'#'\x0d\jzEXITINPUT\x0d\cmpal,13;跳过回车符\x0d\jzINPUTLOOP\x0d\cmpal,10;跳过换行符\x0d\jzINPUTLOOP\x0d\incbyteptr[BUFF+1]\x0d\movbyteptr[bx],al\x0d\incbx\x0d\loopINPUTLOOP\x0d\EXITINPUT:\x0d\ret\x0d\GetInputDataendp\x0d\\x0d\codeends\x0d\\x0d\endSTART
; 从键盘输入N+1个数,对前N个数进行选择排序,再用折半查找判断第N+1个数是否在前N个数中,输出结果。
; 输入数据最大为16位
CODE SEGMENT
ASSUME CS:CODE
START: PUSH CS
POP DS
PUSH CS
POP ES
CALL INPUTNUM
LEA DI,@ARRAY
MOV CX,@NUM
DEC CX
CALL SELECTSORT
MOV AH,2
MOV DL,13
INT 21H
MOV DL,10
INT 21H
LEA SI,@ARRAY
MOV CX,@NUM
DEC CX
CMP CX,0
JZ @EXIT
CLD
@1:
LODSW
CALL DSPAXS
LOOP @1
MOV AH,2
MOV DL,13
INT 21H
MOV DL,10
INT 21H
LEA SI,@ARRAY
MOV CX,@NUM
DEC CX
MOV BX,CX
SHL BX,1
ADD BX,SI
CALL FIND
CALL DSPAXS
@EXIT:
MOV AH,4CH
INT 21H
;==============================================================
; 查找的 元素地址 在 bx,数组首地址 为 si , 元素个数为 cx
; 若找到 ax=找到的序号(从0开始), 否则 ax=-1 (FFFF)
FIND PROC NEAR
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSHF
MOV @X0_F,0
MOV @X1_F, CX
DEC WORD PTR @X1_F
MOV AX,@X0_F
SHL AX,1
ADD AX,SI
MOV DI,AX
MOV AX,[DI]
MOV @Y0_F,AX
MOV AX,@X1_F
SHL AX,1
ADD AX,SI
MOV DI,AX
MOV AX,[DI]
MOV @Y1_F,AX
@FIND0:
MOV AX,@X1_F
SUB AX,@X0_F
CMP AX,1
JL @FINDORNO1
JE @FINDORNO2
MOV AX,@X0_F
ADD AX,@X1_F
SHR AX,1
MOV @XX_F,AX
SHL AX,1
ADD AX,SI
MOV DI,AX
MOV AX,[DI]
MOV @YY_F,AX
MOV DX,@YY_F
MOV AX,@XX_F ;======
CMP [BX],DX
JE @FINDEXIT
JG @FIND1
MOV AX,@XX_F
MOV @X0_F,AX
MOV AX,@YY_F
MOV @Y0_F,AX
JMP @FIND0
@FIND1:
MOV AX,@XX_F
MOV @X1_F,AX
MOV AX,@YY_F
MOV @Y1_F,AX
JMP @FIND0
@FINDEXIT:
POPF
POP DI
POP SI
POP DX
POP CX
POP BX
RET
@FINDORNO1:
MOV AX,@X0_F
MOV DX,@Y0_F
CMP [BX],DX
JE @FINDEXIT
MOV AX,-1
JMP @FINDEXIT
@FINDORNO2:
MOV AX,@X0_F
MOV DX,@Y0_F
CMP [BX],DX
JE @FINDEXIT
MOV AX,@X1_F
MOV DX,@Y1_F
CMP [BX],DX
JE @FINDEXIT
MOV AX,-1
JMP @FINDEXIT
@X0_F DW 0
@X1_F DW 0
@XX_F DW 0
@Y0_F DW 0
@Y1_F DW 0
@YY_F DW 0
FIND ENDP
;===============================================================
; 键盘输入数值数组子程序(数组名为@array,元素个数存放在@num中)
; 可以是负数
; 采用字符串缓冲输入,避免原来键入后不能回退修改的问题 !
INPUTNUM PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSHF
; 对数组@array清零
MOV CX,100
MOV AX,0
LEA DI,@ARRAY
REP STOSW
MOV WORD PTR @NUM,0
; 输入的数据以一个空格分隔,以回车符结束输入
LEA DX,@STRA
MOV AH,10
INT 21H
MOV CL,@STRN
MOV CH,0
MOV WORD PTR @STRM,CX
LEA SI,@STR
CLD
LEA DI,@ARRAY
MOV WORD PTR @NUM,0
@STIN:
MOV AX,0
PUSH AX
MOV BYTE PTR @SIGNN,0
@AGAIN1:
CMP WORD PTR @STRM,0
JE @LINE0
LODSB
DEC WORD PTR @STRM
CMP AL,' '
JE @LINE0
CMP AL,'-'
JNE @INPUT1
MOV BYTE PTR @SIGNN,1
JMP @AGAIN1
@INPUT1:
SUB AL,30H
MOV AH,0
MOV BX,AX
POP AX
MOV CL,10
MOV CH,0
MUL CX
ADD AX,BX
PUSH AX
JMP @AGAIN1
@LINE0:
POP AX
CMP BYTE PTR @SIGNN,1
JNE @INPUT2
NEG AX
@INPUT2:
MOV WORD PTR[DI],AX
INC WORD PTR @NUM
CMP WORD PTR @STRM,0
JE @STINEND
INC DI
INC DI
JMP @STIN
@STINEND:
POPF
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
RET
@STRA DB 255
@STRN DB
@STR DB 255 DUP()
@STRM DW 0
@ARRAY DW 100 DUP(0)
@NUM DW 0
@CHAR DB
@SIGNN DB 0
INPUTNUM ENDP
;=========================================
SELECTSORT PROC NEAR
; 数组起始地址 存入 di,元素个数 存入 cx
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSHF
CMP CX,1
JE @@SELE5
DEC CX ; ################
MOV BX,0
@@SELE1:
PUSH CX
MOV SI,DI
INC SI
INC SI ; {SI=DI+2}
PUSH DI ;{保存DI }
MOV AX,[DI][BX] ; {假设MAX 为第一个}
@@SELE2: MOV DX,[SI][BX] ; {存储器到寄存器,节省时间}
CMP AX,DX
JGE @@SELE3 ; 从大到小,有符号数排序 #################
MOV DI,SI ; {小于时,将SI替换DI,即将J替换I, 保存MAXI}
MOV AX,DX ; {保存MAX 到AX}
@@SELE3: INC SI
INC SI
LOOP @@SELE2
MOV SI,DI ; {还原SI,即将I替换J}
POP DI ; {取出栈中保存的I}
CMP DI,SI ; {与J 比较}
JE @@SELE4 ; {相同时不交换}
MOV AX,[DI][BX] ; {在内循环之外交换}
XCHG AX,[SI][BX]
MOV [DI][BX],AX
@@SELE4: INC BX
INC BX
POP CX
LOOP @@SELE1
@@SELE5:
POPF
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
RET
SELECTSORT ENDP
;==================================
; 输出有符号数,输出的数应放 ax中
DSPAXS PROC NEAR
PUSH AX
OR AX,AX
JNS @DSPAXS
NEG AX
PUSH AX
PUSH DX
MOV AH,2
MOV DL,'-'
INT 21H
POP DX
POP AX
@DSPAXS:
CALL DSPAX
POP AX
RET
DSPAXS ENDP
;===============================
DSPAX PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSHF
XOR CX,CX
MOV BX,10
@DSPAX1:
XOR DX,DX
DIV BX
INC CX
OR DX,30H
PUSH DX
CMP AX,0
JNE @DSPAX1
MOV AH,2
@DISPAX2:
POP DX
INT 21H
LOOP @DISPAX2
MOV DL,32
INT 21H
POPF
POP DX
POP CX
POP BX
POP AX
RET
DSPAX ENDP
;================================
CODE ENDS
END START
;求一个程序,微机原理,8086汇编语言,实现一个简单实用功能,如时钟显示
;
;在右上角显示时钟,按任一键结束
;用MASM50编译通过
data segment
HH DB 0,0,':'
MM DB 0,0,':'
SS1 DB 0,0
data ends
code segment
main proc far
assume cs:code
start:
push ds
mov ax,0
push ax
mov ax,data
mov ds,ax
AGAIN:
mov ah,2ch ;读取系统时间 CH:CL--时:分 DH:DL--秒:百分秒
int 21h
MOV BX ,OFFSET HH
MOV AL,CH
CALL C16_10 ;转换AL中16进制为10进制,并填入相应位置
MOV BX ,OFFSET MM
MOV AL,CL ;分
CALL C16_10
MOV BX ,OFFSET SS1
MOV AL,DH ;秒
CALL C16_10
MOV AH,2 ;光标定位
MOV DH,0 ;首行
MOV DL,70 ;70列
MOV BH,0
INT 10H
MOV CX,8
MOV SI,OFFSET HH
NN1:
MOV AH,0EH ;电传方式写字符(一次1个)
MOV AL,[SI]
MOV BL,0
INT 10H
INC SI
LOOP NN1
MOV AH,1
INT 16H
JNZ DOWN ;按任一键结束
JMP AGAIN
DOWN:
RET
main endp
;============
C16_10 PROC NEAR
PUSH CX ;将AL中的16进制转为10进制
MOV AH,0
MOV CX,10D
DIV CL
ADD AX,3030H
MOV [BX],AL
INC BX
MOV [BX],AH
POP CX
RET
C16_10 ENDP
;=============
code ends
end start
DATASEG SEGMENT ;定义数据段
BUFFER DB 64DUP()
DATASEG ENDS
CODE SEGMENT ;代码段
ASSUME CS: CODE, DS: DATASEG
START: MOV AX,DATASEG
MOV DS, AX
MOV CX, 64
MOV BX,BUFFER
LL: MOV DX,0020H
LLA: IN AL, DX ;查询状态位 设备忙 则等待继续查询
TEST AL,10000000B
JNZ LLA
MOV AL,[BX] ;向外设输出一个字节的数据
MOV DX, 0008H
OUT DX, AL
INC BX ;修改指针
LOOP LL ;循环计数器减1,不等于零,继续循环
CODE ENDS
END
别忘了 该给俺加分了
以上就是关于8086可以把存储器分成几个段各段的地址又怎么确定全部的内容,包括:8086可以把存储器分成几个段各段的地址又怎么确定、求一段8086的汇编语言程序,对50个带符号字节数据进行排序,将排序结果显示出来、用8086汇编语言编写程序键盘输入一段字符以#结束,统计其中数字、字母、空格的个数是多少等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)