2 sumandavg sumandavg 于 2018.01.03 22:58 提问

用8086汇编语言找出10个字节无符号数中的最大数,并进行显示输出。

要求:
数据段提前存好十个无符号数。
得到的最大数也保存在数据段。
利用系统功能调用进行结果的输出。
使用分支和循环程序设计实现。
尽量使用子程序或者宏的程序设计方法使程序整体简洁。
最好写出算法

4个回答

hrbwyf
hrbwyf   2018.01.04 11:10
已采纳

;=================================================================
CODE SEGMENT PUBLIC USE16 'CODE'
ASSUME CS:CODE, DS:DATA,ES:DATA,SS:STACK
SHOW_MSG MACRO msg
push ax
push dx
mov dx,offset msg
mov ah,9
int 21h
pop dx
pop ax
ENDM
SHOW_ASC MACRO
push ax
mov ah,2
int 21h
pop ax
ENDM

ShowDat10 proc
push ax
push bx
push cx
push dx
push si
xor bx,bx
mov si,offset DatAsc
aam
mov bl,ah
mov dl,[si+bx]
SHOW_ASC
mov bl,al
mov dl,[si+bx]
SHOW_ASC
pop si
pop dx
pop cx
pop bx
pop ax
retn
ShowDat10 Endp
START:
mov ax,STACK
mov ss,ax
mov sp,offset StackE
mov ax,DATA
mov ds,ax
SHOW_MSG msg1
mov si,offset dat
mov cx,10
xor bx,bx
cld
LocLoop:
lodsb
cmp al,bl
jb NotG
mov bl,al
NotG:
loop LocLoop
mov ax,bx
call ShowDat10
SHOW_MSG msgCrLf
mov ah,4ch
int 21h
CODE ENDS
;============================================================================
STACK SEGMENT USE16 'STACK'
DB 200h dup ('-STACK- ')
StackE equ $
STACK ENDS
;============================================================================
DATA SEGMENT DWORD PUBLIC USE16 'DATA'
DatAsc db '0123456789ABCDEF'
dat DB 6,3,11,66,34,67,31,33,89,45
msg1 db 'MAX IS $'
msgCrLf db 0dh,0ah,24h
DATA ENDS
END START

hrbwyf
hrbwyf 回复sumandavg: 下面的代码加了注释:),但也加了个错误进去:)
19 天之前 回复
sumandavg
sumandavg 回复溜达1: 能麻烦你简述一下算法或者写一下注释吗?小白,实在看不懂汇编啊
20 天之前 回复
hrbwyf
hrbwyf 好久没写汇编了,希望我的回答对你学习汇编有帮助。
20 天之前 回复
caozhy
caozhy   Ds   Rxr 2018.01.03 23:14
hrbwyf
hrbwyf   2018.01.05 18:13

;谢谢你能采纳我的回答,这是加了注释的代码。
; 1.asm
;======================================================
CODE SEGMENT PUBLIC USE16 'CODE'
ASSUME CS:CODE, DS:DATA,ES:DATA,SS:STACK

SHOW_MSG MACRO msg ;定义了一个显示字符串的宏
push ax
push dx
mov dx,offset msg;要显示的字符串,把地址赋值给DX
mov ah,9
int 21h ;调用DOS系统的中断服务21h,功能AH=9,
;把DX指向的字符串显示到屏幕上,字符串以'$'结束
pop dx
pop ax
ENDM

SHOW_ASC MACRO ;SHOW_ASC宏,显示DL里的字符
push ax
mov ah,2
int 21h ;调用DOS系统的中断服务21H,功能AH=2,把DL里的字符显示到屏幕上
pop ax
ENDM

ShowDat10 proc ;寄存器里的值不可以直接显示,这里用查表法转换成可显示字符
push ax
push bx
push cx
push dx
push si ;保存要用到的寄存器

xor bx,bx   ;BX 清0

mov si,offset DatAsc;字符转换表的地址

aam     ;ASCII调整,这里假设AL调整前是2Ah,
                    ;则调整后AH=02,AL=0Ah

mov bl,ah   ;先处理高位
        ;AH做索引,交给BL,因为前面BX清零了,
        ;   所以这里BX就是AH的索引值

mov dl,[si+bx]  ;你要求是8086汇编,这里就要用si和bx做寻址,
        ;(SI BX是可以做内存寻址的寄存器,AX,CX,DX在8086里不能做寻址)
        ;把 转换表SI + 索引BX 指向的内容(字符)装入DL,
        ;前面假设AH是02的时候,指向的内容就是‘2’ :)

SHOW_ASC    ;装入DL是为了这个宏SHOW_ASC,这个宏把DL的字符显示的屏幕上。

mov bl,al   ;前面高位显示完了,这里al还有低位
        ;把低位值交给BX,BX变成了一个索引

mov dl,[si+bx]  ;把 转换表(si指向)+索引(bx) 里的字符装入DL

SHOW_ASC    ;SHOW_ASC宏,DL里的字符显示到屏幕上

pop si      ;还原前面保存的寄存器
pop dx
pop cx
pop bx
pop ax
retn

ShowDat10 Endp

START:
mov ax,STACK ;初始化各段
mov ss,ax
mov sp,offset StackE
mov ax,DATA
mov ds,ax

SHOW_MSG msg1   ;宏SHOW_MSG,显示信息的前部分 msg1的内容是 'MAX IS '
mov si,offset dat;SI指向10个字节数据段第一个
mov cx,10   ;10个数据,准备用LOOP语句循环10次
xor bx,bx   ;BX准备保存最大数据,先清零
cld     ;

LocLoop:
lodsb ;把SI指向的内容装入AL,SI指向下一个数据
cmp al,bl ;AL装入的值和BL比较
jb NotG ;AL小于BL,不处理,去到下面的LOOP语句
mov bl,al ;到这里,说明AL大于等于前面的BL,把更大的值保存在BL里
NotG:
loop LocLoop ;循环处理CX次
mov ax,bx ;BX里的最大数给AX,为了下面的子程序调用
call ShowDat10 ;把AL里的数转换成可显示字符并显示
SHOW_MSG msgCrLf ;显示一行结束,回车换行
mov ah,4ch ;
int 21h ;AH=4CH,表示通知DOS系统,程序结束了
CODE ENDS
;============================================================================
STACK SEGMENT USE16 'STACK' ;堆栈段

DB 200h dup ('-STACK- ')    ;堆栈预留空间
StackEnd equ $          ;堆栈末端地址

STACK ENDS
;============================================================================
DATA SEGMENT DWORD PUBLIC USE16 'DATA' ;数据段
DatAsc db '0123456789ABCDEF' ;转换表,可显示的ASCII字符
dat DB 6,3,11,66,34,67,31,33,89,45 ;10个字节数据
msg1 db 'MAX IS $' ;显示输出的字符串前部分;这里字符'$'的16进制值是24h
msgCrLf db 0dh,0ah,24h ;显示回车 换行 结束符
DATA ENDS
END START

hrbwyf
hrbwyf   2018.01.05 18:16
; 1.asm
;======================================================
    CODE SEGMENT PUBLIC USE16 'CODE'
    ASSUME CS:CODE, DS:DATA,ES:DATA,SS:STACK

SHOW_MSG MACRO msg  ;定义了一个显示字符串的宏
    push ax
    push dx
    mov dx,offset msg;要显示的字符串,把地址赋值给DX
    mov ah,9
    int 21h ;调用DOS系统的中断服务21h,功能AH=9,
                ;把DX指向的字符串显示到屏幕上,字符串以'$'结束
    pop dx
    pop ax
ENDM

SHOW_ASC MACRO  ;SHOW_ASC宏,显示DL里的字符
    push ax
    mov ah,2
    int 21h ;调用DOS系统的中断服务21H,功能AH=2,把DL里的字符显示到屏幕上
    pop ax
ENDM

ShowDat10 proc      ;寄存器里的值不可以直接显示,这里用查表法转换成可显示字符
    push ax
    push bx
    push cx
    push dx
    push si     ;保存要用到的寄存器

    xor bx,bx   ;BX 清0

    mov si,offset DatAsc;字符转换表的地址

    aam     ;ASCII调整,这里假设AL调整前是2Ah,
                        ;则调整后AH=02,AL=0Ah

    mov bl,ah   ;先处理高位
            ;AH做索引,交给BL,因为前面BX清零了,
            ;   所以这里BX就是AH的索引值

    mov dl,[si+bx]  ;你要求是8086汇编,这里就要用si和bx做寻址,
            ;(SI BX是可以做内存寻址的寄存器,AX,CX,DX在8086里不能做寻址)
            ;把 转换表SI + 索引BX 指向的内容(字符)装入DL,
            ;前面假设AH是02的时候,指向的内容就是‘2’ :)

    SHOW_ASC    ;装入DL是为了这个宏SHOW_ASC,这个宏把DL的字符显示的屏幕上。

    mov bl,al   ;前面高位显示完了,这里al还有低位
            ;把低位值交给BX,BX变成了一个索引

    mov dl,[si+bx]  ;把 转换表(si指向)+索引(bx) 里的字符装入DL

    SHOW_ASC    ;SHOW_ASC宏,DL里的字符显示到屏幕上

    pop si      ;还原前面保存的寄存器
    pop dx
    pop cx
    pop bx
    pop ax
    retn
ShowDat10 Endp

START:
    mov ax,STACK    ;初始化各段
    mov ss,ax
    mov sp,offset StackE
    mov ax,DATA
    mov ds,ax   

    SHOW_MSG msg1   ;宏SHOW_MSG,显示信息的前部分 msg1的内容是 'MAX IS '
    mov si,offset dat;SI指向10个字节数据段第一个
    mov cx,10   ;10个数据,准备用LOOP语句循环10次
    xor bx,bx   ;BX准备保存最大数据,先清零
    cld     ;
LocLoop:
    lodsb       ;把SI指向的内容装入AL,SI指向下一个数据
    cmp al,bl   ;AL装入的值和BL比较
    jb NotG     ;AL小于BL,不处理,去到下面的LOOP语句
    mov bl,al   ;到这里,说明AL大于等于前面的BL,把更大的值保存在BL里
NotG:
    loop LocLoop    ;循环处理CX次
    mov ax,bx   ;BX里的最大数给AX,为了下面的子程序调用
    call ShowDat10  ;把AL里的数转换成可显示字符并显示
    SHOW_MSG msgCrLf ;显示一行结束,回车换行
    mov ah,4ch  ;
    int 21h     ;AH=4CH,表示通知DOS系统,程序结束了
CODE ENDS
;============================================================================
STACK SEGMENT USE16 'STACK' ;堆栈段

    DB 200h dup ('-STACK- ')    ;堆栈预留空间
    StackEnd equ $          ;堆栈末端地址
STACK ENDS
;============================================================================
DATA SEGMENT DWORD PUBLIC USE16 'DATA'  ;数据段
    DatAsc  db '0123456789ABCDEF'       ;转换表,可显示的ASCII字符
    dat DB 6,3,11,66,34,67,31,33,89,45  ;10个字节数据
    msg1    db 'MAX IS $'           ;显示输出的字符串前部分;这里字符'$'的16进制值是24h
    msgCrLf db 0dh,0ah,24h          ;显示回车 换行 结束符
DATA ENDS
END START

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!