一段8086汇编语言写的代码,求解释。

一段8086汇编语言写的代码,求解释。,第1张

这不是《自己动手写 *** 作系统》的示例吗。

这个是内核引导扇区代码,不等同于普通的程序,(这里只是输出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、从键盘输入字符串,对串中的字母进行处理,统计字母数量,同时将大写转换为小写,小等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9494107.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存