4706 字
24 分钟
从零开始的汇编语言笔记(2)
这里应该是一些主要的代码模板记录。
一. 基础读写
1. 单个非负整数输入
控制台输入一个十进制整数字符串,转成数存储。
dataseg segment
input_buffer db 20 input_buffer_len db ? input_buffer_data db 20 dup(?)
input_num dw ?
dataseg ends
codeseg segment assume cs:codeseg, ds:datasegmain proc far push ds xor ax, ax push ax mov ax, dataseg mov ds, ax
call read_num mov ax, input_num
pop ax pop ds mov ax, 4C00h int 21h
main endp
; 输入一个整数,存入input_numread_num proc near push ax push bx push cx push dx push si
mov ah, 0Ah lea dx, input_buffer int 21h
call newline
xor ch, ch mov cl, input_buffer_len mov ax, 0 lea si, input_buffer_data mov bx, 10 xor dx, dx
read_loop: mul bx mov dl, [si] and dl, 0Fh add ax, dx inc si loop read_loop
mov input_num, ax
pop si pop dx pop cx pop bx pop ax retread_num endp
; 换行newline proc near push ax push dx mov ah, 02h
mov dl, 0Dh int 21h mov dl, 0Ah int 21h
pop dx pop ax retnewline endp
codeseg ends
end main2. 单个非负整数输出
; 输出一个整数,存在output_numwrite_num proc near push ax push bx push cx push dx push si
lea si, output_buffer mov ax, output_num
xor dx, dx mov cx, 10 write_loop: div cx ; AX = AX / 10, 商在 AX, 余数在 DX mov bx, dx ; BL = 余数 or bl, 030h ; 转换为 ASCII 字符 mov [si], bl ; 存储字符 inc si ; 指向下一个位置 xor dx, dx
cmp ax, 0 jne write_loop
mov byte ptr [si], '$'
lea di, output_buffer mov cx, si sub cx, di dec si shr cx, 1 jz write_num_print
reverse_loop: mov al, [si] xchg al, [di] xchg al, [si] inc di dec si loop reverse_loop
write_num_print: mov ah, 09h lea dx, output_buffer int 21h
call newline
pop si pop dx pop cx pop bx pop ax retwrite_num endp合并后的输入输出:
dataseg segment
input_buffer db 20 input_buffer_len db ? input_buffer_data db 20 dup(?)
input_num dw ?
output_num dw ? output_buffer db 10 dup (?)
dataseg ends
codeseg segment assume cs:codeseg, ds:dataseg, es:datasegmain proc far push ds xor ax, ax push ax mov ax, dataseg mov ds, ax mov es, ax
call read_num mov ax, input_num
mov output_num, ax call write_num
pop ax pop ds mov ax, 4C00h int 21h
main endp
; 输入一个整数,存入input_numread_num proc near push ax push bx push cx push dx push si
mov ah, 0Ah lea dx, input_buffer int 21h
call newline
xor ch, ch mov cl, input_buffer_len mov ax, 0 lea si, input_buffer_data mov bx, 10 xor dx, dx
read_loop: mul bx mov dl, [si] and dl, 0Fh add ax, dx inc si loop read_loop
mov input_num, ax
pop si pop dx pop cx pop bx pop ax retread_num endp
; 输出一个整数,存在output_numwrite_num proc near push ax push bx push cx push dx push si
lea si, output_buffer mov ax, output_num
xor dx, dx mov cx, 10 write_loop: div cx ; AX = AX / 10, 商在 AX, 余数在 DX mov bx, dx ; BL = 余数 or bl, 030h ; 转换为 ASCII 字符 mov [si], bl ; 存储字符 inc si ; 指向下一个位置 xor dx, dx
cmp ax, 0 jne write_loop
mov byte ptr [si], '$'
lea di, output_buffer mov cx, si sub cx, di dec si shr cx, 1 jz write_num_print
reverse_loop: mov al, [si] xchg al, [di] xchg al, [si] inc di dec si loop reverse_loop
write_num_print: mov ah, 09h lea dx, output_buffer int 21h
call newline
pop si pop dx pop cx pop bx pop ax retwrite_num endp
; 换行newline proc near push ax push dx mov ah, 02h
mov dl, 0Dh int 21h mov dl, 0Ah int 21h
pop dx pop ax retnewline endp
codeseg ends
end main3. 多个非负数输入输出
(1) 每行一个
每行输入1个数。
输入结束后输出。
dataseg segment input_buffer db 20 input_buffer_len db ? input_buffer_data db 20 dup(?) input_num dw ?
output_num dw ? output_buffer db 10 dup (?)
nums_len dw 3 nums dw 3 dup (?)
dataseg ends
codeseg segment assume cs:codeseg, ds:dataseg, es:datasegmain proc near push ds xor ax, ax push ax mov ax, dataseg mov ds, ax mov es, ax
mov cx, [nums_len] lea si, nums get_nums_loop: call read_num mov ax, [input_num] mov word ptr [si], ax add si, 2 loop get_nums_loop
; call sort_num
mov cx, [nums_len] lea si, nums put_nums_loop: mov ax, [si] mov [output_num], ax call write_num add si, 2 loop put_nums_loop
pop ax pop ds mov ax, 4C00h int 21hmain endp
; 输入一个整数,存入input_numread_num proc near push ax push bx push cx push dx push si
mov ah, 0Ah lea dx, input_buffer int 21h
call newline
xor ch, ch mov cl, [input_buffer_len] mov ax, 0 lea si, input_buffer_data mov bx, 10 xor dx, dx
read_loop: mul bx mov dl, [si] and dl, 0Fh add ax, dx inc si loop read_loop
mov [input_num], ax
pop si pop dx pop cx pop bx pop ax retread_num endp
; 输出一个整数,存在output_numwrite_num proc near push ax push bx push cx push dx push si push di
lea si, output_buffer mov ax, [output_num]
xor cx, cx ; 位数计数器 mov bx, 10 write_loop: xor dx, dx div bx ; AX = AX / 10, 商在 AX, 余数在 DX or dl, 030h ; 转换为ASCII码 mov [si], dl ; 存储字符 inc si ; 指向下一个位置 inc cx
cmp ax, 0 jne write_loop
mov byte ptr [si], '$' dec si ; 指向最后一个 lea di, output_buffer ; 指向第一个 shr cx, 1 jz write_num_print ; (防止cx=0时的循环)
reverse_loop: mov al, [si] xchg al, [di] xchg al, [si] inc di dec si loop reverse_loop
write_num_print: mov ah, 09h lea dx, output_buffer int 21h
call newline
pop di pop si pop dx pop cx pop bx pop ax retwrite_num endp
; 换行newline proc near push ax push dx mov ah, 02h
mov dl, 0Dh int 21h mov dl, 0Ah int 21h
pop dx pop ax retnewline endp
codeseg ends
end main(2) 每行多个
读入一行数,存入
input_nums中,并且数的个数存入input_cnt中。
dataseg segment input_nums dw 20 dup(?) input_cnt dw ?
input_invalid db 0
input_buffer db 100 input_buffer_len db ? input_buffer_data db 100 dup(?)
output_num dw ? output_buffer db 10 dup (?)
nums_len dw ? nums dw 20 dup (?)
dataseg ends
stackseg segment db 100 dup (?)stackseg ends
codeseg segment assume cs:codeseg, ds:dataseg, es:dataseg, ss:stacksegmain proc near push ds xor ax, ax push ax mov ax, dataseg mov ds, ax mov es, ax mov ax, stackseg mov ss, ax
call readline_num
call writeline_num
pop ax pop ds mov ax, 4C00h int 21hmain endp
; 输入一行多个整数,存入readline_num proc near push ax push bx push cx push dx push si push di
mov ah, 0Ah lea dx, input_buffer int 21h
call newline
xor ch, ch mov cl, input_buffer_len lea si, input_buffer_data ; 扫描到的原始字符串位置
mov ax, 0 ; 存储当前结果 lea di, input_nums ; 当前正在写入的位置 mov dl, 0 ; 标志位,最低位表示是否有数尚未存入结果 ; 第二位表示是否有负数标志
xor bh, bh
readline_loop: mov bl, byte ptr [si]
cmp bl, ' ' je readline_isspace ; 是空格 cmp bl, 0Dh ; 回车 je readline_isspace cmp bl, 0Ah ; 换行 je readline_isspace cmp bl, '-' je readline_isneg
cmp bl, '0' ; 检查是否是数字 jb readline_invalid cmp bl, '9' ja readline_invalid jmp readline_isnumber
readline_isneg: test dl, 02h ; 多个符号 jnz readline_invalid xor dl, 02h ; 标志位 jmp readline_charover
readline_isspace: test dl, 03h ; 完全没开始 jz readline_charover and dl, 03h cmp dl, 02h ; 检查禁止的情况,仅有一个符号 je readline_invalid test dl, 02h ; 是负数 jz readline_storenum neg ax
readline_storenum: mov word ptr [di], ax ; 存储 xor ax, ax ; 清空 add di, 2 ; 进位
mov dl, 0 ; 标志位清空 jmp readline_charover
readline_isnumber: or dl, 1 ; 标志位 and bl, 0Fh ; ASCII转成数 push dx mov dx, 10 mul dx ; *10 pop dx add ax, bx ; 加当前位
readline_charover: inc si loop readline_loop
; 检查是否有数没有存储 test dl, 01h jz readline_ok
; 处理末尾 mov word ptr [di], ax add di, 2
jmp readline_ok
readline_invalid: ; 非法输入 mov input_invalid, 1
readline_ok:
lea si, input_nums sub di, si sar di, 1
mov input_cnt, di ; 写入个数
pop di pop si pop dx pop cx pop bx pop ax retreadline_num endp
; 输出一行多个整数writeline_num proc near push ax push bx push cx push dx push si push di
lea si, input_nums ; 位置 mov cx, input_cnt ; 长度
writeline_loop: mov ax, word ptr [si] mov output_num, ax
call write_num
mov ah, 02h mov dl, ' ' int 21h
add si, 2 loop writeline_loop
pop di pop si pop dx pop cx pop bx pop ax retwriteline_num endp
; 输出一个整数,存在output_numwrite_num proc near push ax push bx push cx push dx push si push di
lea si, output_buffer mov ax, output_num
; 负数处理 cmp ax, 0 jge direct_write_num push ax mov ah, 02h mov dl, '-' int 21h pop ax neg ax direct_write_num:
xor dx, dx mov cx, 10 write_loop: div cx ; AX = AX / 10, 商在 AX, 余数在 DX mov bx, dx ; BL = 余数 or bl, 030h ; 转换为 ASCII 字符 mov [si], bl ; 存储字符 inc si ; 指向下一个位置 xor dx, dx
cmp ax, 0 jne write_loop
mov byte ptr [si], '$'
lea di, output_buffer mov cx, si sub cx, di dec si shr cx, 1 jz write_num_print
reverse_loop: mov al, [si] xchg al, [di] xchg al, [si] inc di dec si loop reverse_loop
write_num_print: mov ah, 09h lea dx, output_buffer int 21h
; call newline 取决于要不要换行
pop di pop si pop dx pop cx pop bx pop ax retwrite_num endp
; 换行newline proc near push ax push dx mov ah, 02h
mov dl, 0Dh int 21h mov dl, 0Ah int 21h
pop dx pop ax retnewline endp
codeseg ends
end main二. 常见任务
1. 排序
一个简单的选择排序:
dataseg segment input_buffer db 20 input_buffer_len db ? input_buffer_data db 20 dup(?) input_num dw ?
output_num dw ? output_buffer db 10 dup (?)
nums_len dw ? nums dw 20 dup (?)
prompt_input_num db 'Input the number of numbers: ', '$' prompt_input_num_d db 'Input the number: ', '$'
dataseg ends
codeseg segment assume cs:codeseg, ds:dataseg, es:datasegmain proc near push ds xor ax, ax push ax mov ax, dataseg mov ds, ax mov es, ax
mov ah, 09h lea dx, prompt_input_num int 21h call read_num
mov ah, 09h lea dx, prompt_input_num_d int 21h
mov cx, input_num mov nums_len, cx lea si, nums
get_nums_loop: call read_num mov ax, input_num mov word ptr [si], ax add si, 2 loop get_nums_loop
call sort_num
mov cx, nums_len lea si, nums put_nums_loop: mov ax, word ptr [si] mov output_num, ax call write_num add si, 2 loop put_nums_loop
pop ax pop ds mov ax, 4C00h int 21hmain endp
sort_num proc near push ax push bx push cx push dx push si push di
mov si, [nums_len] sal si, 1 lea bx, [nums + si] ; 截止位 lea si, nums
sort_loop:
lea di, [si + 2] cmp di, bx je scan_over
scan_loop: mov ax, word ptr [di] cmp word ptr [si], ax jna scan_loop_over ; 开始交换 mov ax, word ptr [si] xchg ax, word ptr [di] xchg ax, word ptr [si] scan_loop_over: add di, 2 cmp di, bx jne scan_loop
scan_over: add si, 2 cmp si, bx jne sort_loop
pop di pop si pop dx pop cx pop bx pop ax
retsort_num endp
; 输入一个整数,存入input_numread_num proc near push ax push bx push cx push dx push si
mov ah, 0Ah lea dx, input_buffer int 21h
call newline
xor ch, ch mov cl, input_buffer_len mov ax, 0 lea si, input_buffer_data mov bx, 10 xor dx, dx
read_loop: mul bx mov dl, [si] and dl, 0Fh add ax, dx inc si loop read_loop
mov input_num, ax
pop si pop dx pop cx pop bx pop ax retread_num endp
; 输出一个整数,存在output_numwrite_num proc near push ax push bx push cx push dx push si
lea si, output_buffer mov ax, output_num
xor dx, dx mov cx, 10 write_loop: div cx ; AX = AX / 10, 商在 AX, 余数在 DX mov bx, dx ; BL = 余数 or bl, 030h ; 转换为 ASCII 字符 mov [si], bl ; 存储字符 inc si ; 指向下一个位置 xor dx, dx
cmp ax, 0 jne write_loop
mov byte ptr [si], '$'
lea di, output_buffer mov cx, si sub cx, di dec si shr cx, 1 jz write_num_print
reverse_loop: mov al, [si] xchg al, [di] xchg al, [si] inc di dec si loop reverse_loop
write_num_print: mov ah, 09h lea dx, output_buffer int 21h
call newline
pop si pop dx pop cx pop bx pop ax retwrite_num endp
; 换行newline proc near push ax push dx mov ah, 02h
mov dl, 0Dh int 21h mov dl, 0Ah int 21h
pop dx pop ax retnewline endp
codeseg ends
end main
2. 进制转换
输入一个十进制数,转成十六进制输出。
*报错
operand must have size
mov [si], '$'应该修改为
mov byte ptr [si], '$'Expected: comma
shr cx没有指定位移的位数。
shr cx, 1往年上机题
2021级:输入一组数,输出中位数
也就是前面排序的类似的,取出中间的数即可。
dataseg segment input_buffer db 20 input_buffer_len db ? input_buffer_data db 20 dup(?) input_num dw ?
output_num dw ? output_buffer db 10 dup (?)
nums_len dw ? nums dw 20 dup (?)
prompt_input_num db 'Input the number of numbers: ', '$' prompt_input_num_d db 'Input the number: ', '$' prompt_mid db 'The middle is : ', '$'
dataseg ends
codeseg segment assume cs:codeseg, ds:dataseg, es:datasegmain proc near push ds xor ax, ax push ax mov ax, dataseg mov ds, ax mov es, ax
mov ah, 09h lea dx, prompt_input_num int 21h call read_num
mov ah, 09h lea dx, prompt_input_num_d int 21h
mov cx, input_num mov nums_len, cx lea si, nums
get_nums_loop: call read_num mov ax, input_num mov word ptr [si], ax add si, 2 loop get_nums_loop
call sort_num
mov ah, 09h lea dx, prompt_mid int 21h
mov cx, nums_len inc cx shr cx, 1 ; (n+1)/2 dec cx ; 调整为零基 shl cx, 1 ; 2字节一个字
lea si, nums add si, cx
mov ax, word ptr [si] mov output_num, ax call write_num
pop ax pop ds mov ax, 4C00h int 21hmain endp
sort_num proc near push ax push bx push cx push dx push si push di
mov si, [nums_len] sal si, 1 lea bx, [nums + si] ; 截止位 lea si, nums
sort_loop:
lea di, [si + 2] cmp di, bx je scan_over
scan_loop: mov ax, word ptr [di] cmp word ptr [si], ax jna scan_loop_over ; 开始交换 mov ax, word ptr [si] xchg ax, word ptr [di] xchg ax, word ptr [si] scan_loop_over: add di, 2 cmp di, bx jne scan_loop
scan_over: add si, 2 cmp si, bx jne sort_loop
pop di pop si pop dx pop cx pop bx pop ax
retsort_num endp
; 输入一个整数,存入input_numread_num proc near push ax push bx push cx push dx push si
mov ah, 0Ah lea dx, input_buffer int 21h
call newline
xor ch, ch mov cl, input_buffer_len mov ax, 0 lea si, input_buffer_data mov bx, 10 xor dx, dx
read_loop: mul bx mov dl, [si] and dl, 0Fh add ax, dx inc si loop read_loop
mov input_num, ax
pop si pop dx pop cx pop bx pop ax retread_num endp
; 输出一个整数,存在output_numwrite_num proc near push ax push bx push cx push dx push si
lea si, output_buffer mov ax, output_num
xor dx, dx mov cx, 10 write_loop: div cx ; AX = AX / 10, 商在 AX, 余数在 DX mov bx, dx ; BL = 余数 or bl, 030h ; 转换为 ASCII 字符 mov [si], bl ; 存储字符 inc si ; 指向下一个位置 xor dx, dx
cmp ax, 0 jne write_loop
mov byte ptr [si], '$'
lea di, output_buffer mov cx, si sub cx, di dec si shr cx, 1 jz write_num_print
reverse_loop: mov al, [si] xchg al, [di] xchg al, [si] inc di dec si loop reverse_loop
write_num_print: mov ah, 09h lea dx, output_buffer int 21h
call newline
pop si pop dx pop cx pop bx pop ax retwrite_num endp
; 换行newline proc near push ax push dx mov ah, 02h
mov dl, 0Dh int 21h mov dl, 0Ah int 21h
pop dx pop ax retnewline endp
codeseg ends
end main2021级:输入字符串,改成小写后按字母表输出
终端输入一个字符串
程序要求:
将大写字母改为小写。
按a-z的顺序输出出现过的字母
如果字母没有出现就用空格代替,不能重复输出相同字母
(大概从0开始写了20min)
dataseg segment input_buffer db 20 input_buffer_len db ? input_buffer_data db 20 dup (?)
answer_buffer db 26 dup (' '), '$'
dataseg ends
codeseg segment assume cs:codeseg, ds:dataseg, es:datasegmain proc near push ds xor ax, ax push ax mov ax, dataseg mov ds, ax mov es, ax
mov ah, 0ah lea dx, input_buffer int 21h
call newline
xor ch, ch mov cl, input_buffer_len lea si, input_buffer_data
mov bl, byte ptr 'a' sub bl, byte ptr 'A'
; 改成小写 search_loop: mov al, byte ptr [si] cmp al, byte ptr 'A' jb no_match cmp al, byte ptr 'Z' ja no_match
add al, bl mov byte ptr [si], al
no_match:
inc si loop search_loop
mov byte ptr [si], '$'
; mov ah, 09h ; lea dx, input_buffer_data ; int 21h
; call newline
xor ch, ch mov cl, input_buffer_len lea si, input_buffer_data
solve_loop: mov al, byte ptr [si]
cmp al, byte ptr 'a' jb solve_loop_over cmp al, byte ptr 'z' ja solve_loop_over
mov bl, al sub bl, byte ptr 'a'
xor bh, bh lea di, answer_buffer add di, bx
mov [di], byte ptr 'a' add [di], bl
solve_loop_over: inc si loop solve_loop
mov ah, 09h lea dx, answer_buffer int 21h
call newline
pop ax pop ds mov ax, 4C00h int 21hmain endp
newline proc near push ax push ds mov ah, 02h
mov dl, 0Dh int 21h mov dl, 0ah int 21h
pop dx pop ax retnewline endp
codeseg ends
end main2020级:接受十进制数输入朝代,将朝代转成对应年份输出
- 自行设计数据存储朝代
- 接收一个十进制年份输入
- 将年份转为相应的朝代字符串输出
- 查询可重复,如不是合法输入则退出程序
dataseg segment input_buffer db 20 input_buffer_len db ? input_buffer_data db 20 dup(?) input_num dw ?
input_prompt db 'Input Year: ', '$'
year_cnt dw 7 year_ans dw -10000, -500, 800, 1000, 1300, 1500, 1700, 10000 dyna_ans db 'Qin $Han $Tang$Song$Yuan$Ming$Qing$'
invalid_tag db 0
dataseg ends
codeseg segment assume cs:codeseg, ds:dataseg, es:datasegmain proc near push ds xor ax, ax push ax mov ax, dataseg mov ds, ax mov es, ax
main_loop: mov ah, 09h lea dx, input_prompt int 21h
call read_num mov al, invalid_tag cmp al, 1
je main_over call answer jmp main_loop
main_over: pop ax pop ds mov ax, 4C00h int 21hmain endp
answer proc near mov cx, year_cnt lea si, year_ans lea di, dyna_ans
mov dx, input_num answer_loop: mov ax, [si] mov bx, [si+2] cmp dx, ax jl no_answer cmp dx, bx jge no_answer jmp answer_find no_answer: add si, 2 add di, 5 loop answer_loop
answer_find: mov ah, 09h mov dx, di int 21h
call newline
retanswer endp
read_num proc near push ax push bx push cx push dx push si push di
mov ah, 0Ah lea dx, input_buffer int 21h
call newline
xor ch, ch mov cl, [input_buffer_len] mov ax, 0 lea si, input_buffer_data mov bx, 10 xor dx, dx
mov dl, [si] cmp dl, '-' jne read_loop inc si dec cx
read_loop: mul bx mov dl, [si]
cmp dl, '0' jb read_invalid cmp dl, '9' ja read_invalid
and dl, 0Fh add ax, dx inc si loop read_loop
lea si, input_buffer_data mov dl, [si] cmp dl, '-' jne read_store neg ax read_store: mov [input_num], ax
jmp read_num_over
read_invalid: mov ax, 1 mov invalid_tag, al read_num_over: pop di pop si pop dx pop cx pop bx pop ax retread_num endp
newline proc near push ax push dx mov ah, 02h
mov dl, 0Dh int 21h mov dl, 0Ah int 21h
pop dx pop ax retnewline endp
codeseg ends
end main2020级:加减法表达式
dataseg segment input_nums dw 20 dup(?) input_cnt dw ?
input_invalid db 0
input_buffer db 100 input_buffer_len db ? input_buffer_data db 100 dup(?)
fuhao db ?
output_num dw ? output_buffer db 10 dup (?)
nums_len dw ? nums dw 20 dup (?)
dataseg ends
stackseg segment db 100 dup (?)stackseg ends
codeseg segment assume cs:codeseg, ds:dataseg, es:dataseg, ss:stacksegmain proc near push ds xor ax, ax push ax mov ax, dataseg mov ds, ax mov es, ax mov ax, stackseg mov ss, ax
call readline_num
mov ax, [input_nums] mov bx, [input_nums+2]
mov cl, fuhao cmp cl, '+' je adddd jne deccc
adddd: add ax, bx jmp main_overdeccc: sub ax, bxmain_over: mov input_nums, ax mov ax, 1 mov input_cnt, ax call writeline_num
pop ax pop ds mov ax, 4C00h int 21hmain endp
; 输入一行多个整数,存入readline_num proc near push ax push bx push cx push dx push si push di
mov ah, 0Ah lea dx, input_buffer int 21h
call newline
xor ch, ch mov cl, input_buffer_len lea si, input_buffer_data ; 扫描到的原始字符串位置
mov ax, 0 ; 存储当前结果 lea di, input_nums ; 当前正在写入的位置 mov dl, 0 ; 标志位,最低位表示是否有数尚未存入结果 ; 第二位表示是否有负数标志
xor bh, bh
readline_loop: mov bl, byte ptr [si]
cmp bl, '-' je readline_isspace cmp bl, '+' je readline_isspace
cmp bl, '0' ; 检查是否是数字 jb readline_invalid cmp bl, '9' ja readline_invalid jmp readline_isnumber
readline_isspace: test dl, 03h ; 完全没开始 jz readline_charover and dl, 03h cmp dl, 02h ; 检查禁止的情况,仅有一个符号 je readline_invalid test dl, 02h ; 是负数 jz readline_storenum neg ax
readline_storenum: mov word ptr [di], ax ; 存储 xor ax, ax ; 清空 add di, 2 ; 进位 mov fuhao, bl
mov dl, 0 ; 标志位清空 jmp readline_charover
readline_isnumber: or dl, 1 ; 标志位 and bl, 0Fh ; ASCII转成数 push dx mov dx, 10 mul dx ; *10 pop dx add ax, bx ; 加当前位
readline_charover: inc si loop readline_loop
; 检查是否有数没有存储 test dl, 01h jz readline_ok
; 处理末尾 mov word ptr [di], ax add di, 2
jmp readline_ok
readline_invalid: ; 非法输入 mov input_invalid, 1
readline_ok:
lea si, input_nums sub di, si sar di, 1
mov input_cnt, di ; 写入个数
pop di pop si pop dx pop cx pop bx pop ax retreadline_num endp
; 输出一行多个整数writeline_num proc near push ax push bx push cx push dx push si push di
lea si, input_nums ; 位置 mov cx, input_cnt ; 长度
writeline_loop: mov ax, word ptr [si] mov output_num, ax
call write_num
mov ah, 02h mov dl, ' ' int 21h
add si, 2 loop writeline_loop
pop di pop si pop dx pop cx pop bx pop ax retwriteline_num endp
; 输出一个整数,存在output_numwrite_num proc near push ax push bx push cx push dx push si push di
lea si, output_buffer mov ax, output_num
; 负数处理 cmp ax, 0 jge direct_write_num push ax mov ah, 02h mov dl, '-' int 21h pop ax neg ax direct_write_num:
xor dx, dx mov cx, 10 write_loop: div cx ; AX = AX / 10, 商在 AX, 余数在 DX mov bx, dx ; BL = 余数 or bl, 030h ; 转换为 ASCII 字符 mov [si], bl ; 存储字符 inc si ; 指向下一个位置 xor dx, dx
cmp ax, 0 jne write_loop
mov byte ptr [si], '$'
lea di, output_buffer mov cx, si sub cx, di dec si shr cx, 1 jz write_num_print
reverse_loop: mov al, [si] xchg al, [di] xchg al, [si] inc di dec si loop reverse_loop
write_num_print: mov ah, 09h lea dx, output_buffer int 21h
; call newline 取决于要不要换行
pop di pop si pop dx pop cx pop bx pop ax retwrite_num endp
; 换行newline proc near push ax push dx mov ah, 02h
mov dl, 0Dh int 21h mov dl, 0Ah int 21h
pop dx pop ax retnewline endp
codeseg ends
end main