就是要努力呀 发表于 2020-6-23 17:37:36

实验17

本帖最后由 就是要努力呀 于 2020-6-23 17:46 编辑

最后一个实验作业了,用了两个半天时间,可以手动输入逻辑扇区号和读写命令
assume cs:code, ds:data, ss:data_stack, ss:char_stack

data segment
        menu        dw        first, second
        first                db        'please enter the logical sector number:', 0
        second        db        'please enter the action you want to take(0.in, 1.out):', 0
        number        db        0, 0, 0        ;分别存放面,道,扇区
        stack_sp        dw        1024, 1024        ;分别保存data_stack的sp和char_stack的sp
data ends

data_stack segment
        db        1024 dup(0)
data_stack ends

char_stack segment
        db        1024 dup(0)
char_stack ends

code segment
start:        mov ax, data
                mov ds, ax
                mov si, 0
               
                mov ax, data_stack
                mov ss, ax
                mov sp, 1024
               
                mov ax, 0b800h
                mov es, ax
               
                ;打印第一句话
                mov ah, 0
                ;dh表示行,dl表示列
                mov dh, 1
                mov dl, 0
                call print
               
                ;获取输入
                call get_numer
                ;将字符形式的输入转换成16进制的数字
                call change_16
                ;dx中存放着逻辑扇区号
               
                ;根据逻辑扇区号计算出物理扇区号
               
                ;计算面号
                mov ax, dx
                mov dx, 0
                mov bx, 1440
                div bx
                mov number, al

                ;计算磁道号
                mov ax, dx
                mov bl, 18
                div bl
                mov number, al
               
                ;计算扇区号
                add ah, 1
                mov number, ah
               
                ;打印第二句话
                mov ah, 1
                ;dh表示行,dl表示列
                mov dh, 2
                mov dl, 0
                call print
               
                ;获取输入
                call get_numer
                call change_16
                ;将change_16的返回值放入ah中
                mov ax, dx
                mov ah, al
                mov al, 1
                add ah, 2
                ;ah中存放着功能号,al中存放着要读取的扇区数
               
                ;开始读写
                mov bx, 0
                mov es, bx
                mov bx, 200h
               
                mov dh, number        ;面号
                mov dl, 0                        ;驱动器号
                mov ch, number        ;磁道号
                mov cl, number        ;扇区号
               
                int 13h

                mov ax, 4c00h
                int 21h

print:        push bx
                push ax
                push dx
                push cx
                push es
               
                ;根据ah计算出要打印的句子在内存中的偏移地址
                mov bl, ah
                mov bh, 0
                add bx, bx
                mov bx, menu
               
                ;根据dx计算处打印的行和列
                mov al, 160
                mul dh
                mov di, ax
                mov al, 2
                mul dl
                add di, ax
               
                mov ch, 0
        print_start:
                        mov cl, ds:
                        jcxz return0
                        mov es:, cl
                        add di, 2
                        inc bx
                        jmp short print_start
                       
        return0: pop es
                        pop cx
                        pop dx
                        pop ax
                        pop bx
                        ret
                       
get_numer:
                push ax
                push es
               
                ;保存数据栈段的sp
                mov stack_sp, sp
               
                ;使用字符栈段
                mov ax, char_stack
                mov ss, ax
                mov sp, stack_sp
               
        get_numer_start:
                        mov ah, 0
                        int 16h
                        cmp al, 20h        ;如果ascii小于20h,说明不是字符
                        jb not_char

                        ;字符入栈
                        mov ah, 0
                        push ax
                        mov es:, al
                        add di, 2
                        jmp get_numer_start

        not_char:
                        cmp ah, 0eh        ;检测是否是退格键的扫描码
                        je        backspace
                        cmp ah, 1ch        ;检测是否是会车键的扫描码
                        je _enter


        backspace:
                        cmp sp, 1024        ;判断栈是否为空栈
                        je get_numer_start
                        sub di, 2
                        mov byte ptr es:, ' '
                        pop ax
                        jmp short get_numer_start
                       

        _enter:        ;保存字符栈段的sp
                        mov stack_sp, sp
                       
                        ;使用数据栈段
                        mov ax, data_stack
                        mov ss, ax
                        mov sp, stack_sp
                       
                        pop es
                        pop ax
                        ret
                       
change_16:        push ax
                        push bx
                        push cx
                        ;保存数据栈段的sp
                        mov stack_sp, sp
                       
                        ;使用字符栈段
                        mov ax, char_stack
                        mov ss, ax
                        mov sp, stack_sp
                       
                        ;将栈的字符型转换成对应的16进制数字
                        mov dx, 0
                        mov bx, 0
                        mov cx, 1
                       
        change_16_start:
                        cmp sp, 1024
                        je return1
                        pop ax
                        sub al, 30h
                        mul cl
                        add dx, ax
                        mov al, 10
                        mul cl
                        mov cx, ax
                        jmp short change_16_start
                        ;运行完后dx中就是输入的数字的16进制
                       
                        ;保存字符栈段的sp
                        mov stack_sp, sp
                       
                        ;使用数据栈段
        return1:       
                        mov ax, data_stack
                        mov ss, ax
                        mov sp, stack_sp
                       
                        pop cx
                        pop bx
                        pop ax
                        ret
code ends

end start
页: [1]
查看完整版本: 实验17