这不是《自己动手写 *** 作系统》的示例吗。
这个是内核引导扇区代码,不等同于普通的程序,(这里只是输出hello world)
用nasm语言写成
1 org 0x7c00 因为计算机会将本段放置0x7c00位置,所以此时需要声明偏移(cs=0x7c00)
接下来,将ss,cs,ds设成0x7c00,这样,才可计算数据、堆栈偏移
2 call会将ip指向函数入口,这是典型的函数调用
$表示本指令地址,jmp $表示,跳至本处地址(即死循环)
3 函数内部
int 0x10 中断表示输出,那些mov是给中断提供参数
具体寄存器参数请参考google
4 times 表示重复, 这里就是重复若干(510 - ($-$$))个0
$$表示本段地址,此句含义是将程序大小扩至512字节。
5 0xaa55指引导扇区标志,也就是说,计算机在510字节处发现0xaa55,则认为这是引导扇区
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
之前回答的一个问题,只是少了统计数量的
model small
stack 100h
data
buf label byte
max_len db 255
str_len db 0
str_buf db 256 dup(0)
code
main proc
mov ax, @data ;初始化数据段
mov ds, ax
mov es, ax
mov ah, 0ah ;键盘输入
lea dx, buf ;缓冲区 DS:DX=buf
int 21h
mov ah, 02h ;回车换行
mov dl, 0dh
int 21h
mov dl, 0ah
int 21h
lea si, str_buf ;获取输入字符串地址
mov di, si
mov dx, si ;保存DX中,用于INT21 09号功能显示字符串
mov bl, byte ptr [str_len] ;获取输入字符串长度
xor bh, bh
mov byte ptr [bx][si], '$' ;在字符串末尾添加一个 '$',用于用于INT21 09号功能显示字符串终止符
mov cx, bx ;获取字符串长度,控制循环次数
cld
@@1:
lodsb
cmp al, 'A' ;<'A 不是大写字母
jb @@3
cmp al, 'Z' ;>'Z'不是大写字母
ja @@2
add al, 'a'-'A' ; ;大写变小写
jmp short @@3
@@2:
cmp al, 'a' ;<'a'不是小写字母
jb @@3
cmp al, 'z' ;>'z'不是小写字母
ja @@3
sub al, 'a'-'A' ; ;小写变大写
@@3:
stosb ;
loop @@1
mov ah, 09h ;显示字符串,DS:DX
int 21h
mov ax, 4c00h ;正常退出
int 21h
main endp
end main
题目没写明白:
没说清array里是所有人的成绩还是只这几个人的;
没说清是所有人都加5分还是只是低于80的加;
没说清总分是所有人的还是只这几个人的、是加分后的还是加分前的;
只好按我的理解来写:
array里可能是全班人的成绩(比如20个人)
只是给不够80分人的加5分、并且只显示出这些人加分后的成绩
总分是所有人调整后的分数和
另外注意程序是把所有低于80分的都处理(而不是数7个完事)
程序如下:
students equ 20
model small
stack 2048
data
array db 100,99,88,77,66,90,80,70,60,40,20,91,95,96,79,76,55,99,100,88
new db students dup ()
sum dw 0
crlf db 13,10,36
txt db 'SUMMARY OF CLASS: $'
code
main: mov ax,seg array
mov ds,ax
mov es,ax
mov si,offset array ;将使用lodsb从array中读入分数(由ds:si定位)
mov di,offset new ;并按要求将新分数存至new中(由es:di定位)
mov cx,students ;学生人数即循环次数
cld ;为lodsb/stosb指令清除方向标志
mov bx,1 ;为输出美观,用bx当学号吧
lp: mov dl,'(' ;这段输出学号,学号两边用括号扩起来
call putc
push bx ;学号
call print
mov dl,')'
call putc
mov dl,9 ;用制表符分开
call putc
lodsb ;从array数组读一个分数(字节型数据)
xor ah,ah ;ah清零,算总分时是要加上高8位的
cmp al,80 ;是否高于80分
jae above80 ;大于或等于80分的跳过
add al,5 ;低于80的加5分
mov dl,'' ;先输出一个星号表示该成绩是调整后的成绩
call putc
above80: stosb ;所有人的最终成绩存回new数组
add sum,ax ;最终成绩加到总分里
push ax ;输出该生最终成绩
call print
mov dx,offset crlf ;回车换行
call puts
inc bx ;假装学号加1
loop lp ;循环
call puts ;再换行一下
mov dx,offset txt ;输出全班总分的标题
call puts
mov ax,sum
push ax
call print ;输出总分
mov dx,offset crlf ;回车换行
call puts
mov ah,4ch ;程序结束
int 21h
print proc near
mov bp,sp
push ax
push bx
push cx
push dx
mov ax,[bp+2]
call printax
pop dx
pop cx
pop bx
pop ax
ret 2
print endp
;以10进制输出ax中的无符号整数
printax proc
mov bx,10 ;bx是除数
or ax,ax ;是0则直接输出
jnz @f
mov dl,'0'
call putc
ret
@@: xor dx,dx
div bx
mov cx,ax
or cx,dx ;若商与余数都为0则结束递归
jz @f
push dx ;留存DX中的余数以在递归后输出
call @b ;递归
pop dx ;从最高位开始恢复余数
add dl,'0'
call putc
@@: ret
printax endp
putc proc
push ax
mov ah,2
int 21h
pop ax
ret
putc endp
puts proc
push ax
mov ah,9
int 21h
pop ax
ret
puts endp
end main
执行结果:
(1) 100
(2) 99
(3) 88
(4) 82
(5) 71
(6) 90
(7) 80
(8) 75
(9) 65
(10) 45
(11) 25
(12) 91
(13) 95
(14) 96
(15) 84
(16) 81
(17) 60
(18) 99
(19) 100
(20) 88
SUMMARY OF CLASS: 1614
;======================
DISP_STR MACRO X ;宏定义
MOV DX, OFFSET X
MOV AH, 9
INT 21H
ENDM
;----------------------
DATA SEGMENT ;数据段
MSG1 DB 13, 10, 'Please Input : $'
MSG3 DB 13, 10, 'The HEX is : $'
x DW ;存放新输入数据
DATA ENDS
;----------------------
CODE SEGMENT ;代码段
ASSUME CS: CODE, DS: DATA
START:
MOV AX, DATA
MOV DS, AX
;--------------------------------
IN_LOOP:
DISP_STR MSG1 ;宏调用,提示 Please Input :
;--------------------------------
MOV x, 0 ;数据清零
_INX:
MOV AH, 1 ;输入字符
INT 21H
;--------------------------------
CMP AL, 13 ;回车
JE _IN_END ;是则结束输入
CMP AL, '0'
JB IN_LOOP ;小于'0',不是数字
CMP AL, '9'
JA IN_LOOP ;大于'9',不是数字
SUB AL, '0'
MOV CL, AL
MOV CH, 0
MOV AX, x
MOV BX, 10 ;老数据乘以10
MUL BX
ADD AX, CX ;加上新数据
MOV x, AX ;保存
CMP AX, 99
JA IN_LOOP
JMP _INX
;--------------------------------
_IN_END:
DISP_STR MSG3 ;宏调用,提示 The HEX is :
MOV AX, x
MOV BX, 16
MOV CX, 0
D_1:MOV DX, 0
DIV BX
ADD DL, '0'
CMP DL, 3AH
JB ZZZ
ADD DL, 7
ZZZ:
PUSH DX
INC CX
CMP AX, 0
JNE D_1
MOV AH, 2
D_2:POP DX
INT 21H
LOOP D_2
;--------------------------------
MOV AH, 4CH
INT 21H
;--------------------------------
CODE ENDS
END START
;=====================
以上就是关于一段8086汇编语言写的代码,求解释。全部的内容,包括:一段8086汇编语言写的代码,求解释。、用8086汇编语言编写程序键盘输入一段字符以#结束,统计其中数字、字母、空格的个数是多少、急求8086汇编程序: 1、从键盘输入字符串,对串中的字母进行处理,统计字母数量,同时将大写转换为小写,小等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)