SHR32 MACRO A,B,C LOCAL LOOPS_MACRO PUSH AX PUSH DX PUSH CX MOV AX,A MOV DX,B MOV CX,C LOOPS_MACRO: ROR DX,1 ROL DX,1 RCR AX,1 SAR DX,1 LOOP LOOPS_MACRO MOV SHRL,AX MOV SHRH,DX POP CX POP DX POP AX ENDM
时间: 2023-06-08 11:07:06 浏览: 86
我理解您的问题是关于 SHR32 MACRO A,B,C 的指令,它是将 A 和 B 进行二进制右移位运算(相当于除以2的C次方),然后将结果存储在 LO 字节的 SHRL 中,将 HI 字节的结果存储在 SHRH 中。这里的 LO 和 HI 指的是 AX 和 DX 的低字节和高字节。指令的执行过程中,采用了循环控制结构,LOOPS_MACRO 标签之后的指令会被循环执行,执行次数是由 CX 寄存器指定的。
相关问题
XIAN PROC ;对时间值进行处理并显示的子程序 PUSH SI PUSH DI PUSH DX PUSH CX PUSH BX PUSH AX POP AX PUSH AX MOV BX,AX MOV AX,0 MOV AL,BH MOV CL,4 SHR AL,CL MOV BL,AL MOV DH,10 MOV DL,2 CALL FF POP AX PUSH AX MOV BX,AX MOV AX,0 MOV AL, BH AND AL,0FH MOV BL,AL MOV DH,10 MOV DL,6 CALL FF MOV DH,10 MOV DL,10 MOV BL,10 请帮我把没有注释的加上注释
; XIAN PROC - 时间值处理并显示的子程序
PUSH SI ; 保存 SI 寄存器
PUSH DI ; 保存 DI 寄存器
PUSH DX ; 保存 DX 寄存器
PUSH CX ; 保存 CX 寄存器
PUSH BX ; 保存 BX 寄存器
PUSH AX ; 保存 AX 寄存器
POP AX ; 弹出 AX 寄存器的值
PUSH AX ; 将 AX 寄存器的值压入栈中
MOV BX,AX ; 将 AX 寄存器的值传递给 BX 寄存器
MOV AX,0 ; 将 AX 寄存器的值清零
MOV AL,BH ; 将 BX 寄存器的高位传递给 AL 寄存器
MOV CL,4 ; 将数值 4 传递给 CL 寄存器
SHR AL,CL ; 右移 AL 寄存器的值 4 位,并将结果传递给 AL 寄存器
MOV BL,AL ; 将 AL 寄存器的值传递给 BL 寄存器
MOV DH,10 ; 将数值 10 传递给 DH 寄存器
MOV DL,2 ; 将数值 2 传递给 DL 寄存器
CALL FF ; 调用 FF 子程序
POP AX ; 弹出 AX 寄存器的值
PUSH AX ; 将 AX 寄存器的值压入栈中
MOV BX,AX ; 将 AX 寄存器的值传递给 BX 寄存器
MOV AX,0 ; 将 AX 寄存器的值清零
MOV AL, BH ; 将 BX 寄存器的高位传递给 AL 寄存器
AND AL, 0FH ; 将 AL 寄存器的值与数值 0FH 进行按位与操作,结果传递给 AL 寄存器
MOV BL,AL ; 将 AL 寄存器的值传递给 BL 寄存器
MOV DH,10 ; 将数值 10 传递给 DH 寄存器
MOV DL,6 ; 将数值 6 传递给 DL 寄存器
CALL FF ; 调用 FF 子程序
MOV DH,10 ; 将数值 10 传递给 DH 寄存器
MOV DL,10 ; 将数值 10 传递给 DL 寄存器
MOV BL,10 ; 将数值 10 传递给 BL 寄存器
完善assume cs:code,ds:data data segment db 'welcome to masm!',0 data ends code segment start:mov dh,8 mov dl,3 mov cl,2 mov ax,data mov ds,ax mov si,0 call show_str mov ax,4c00h int 21h show_str: push ax push bx push es push si push cx mov ax,0b800h mov es,ax mov ax,160 mul dh mov bx,ax mov ax,2 mul dl add bx,ax mov al,cl mov cl,0 show0: mov ch,[si] jcxz show1 mov es:[bx],ch mov es:[bx].1,al inc si add bx,2 jmp show0 show1: pop cx pop si pop es pop bx pop ax ret code ends end start使其能在屏幕中间分别显示绿色、绿底红色、白底蓝色的‘welcome to masm’。
在原有代码的基础上,我们需要对 `show_str` 进行修改,以便可以在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串。
修改后的代码如下:
```
show_str:
push ax
push bx
push es
push si
push cx
; 显示绿色字符串
mov ax, 0B800h
mov es, ax
mov ax, 160
mul dh
mov bx, ax
mov ax, 2
mul dl
add bx, ax
mov al, 2 ; 前景色为绿色
mov cl, 0 ; 背景色为黑色
mov si, offset data
call show_line
; 显示绿底红色字符串
mov ax, 0B800h
mov es, ax
mov ax, 160
mul dh
mov bx, ax
mov ax, 2
mul dl
add bx, ax
mov al, 4 ; 前景色为红色,背景色为绿色
mov cl, 2
mov si, offset data
call show_line
; 显示白底蓝色字符串
mov ax, 0B800h
mov es, ax
mov ax, 160
mul dh
mov bx, ax
mov ax, 2
mul dl
add bx, ax
mov al, 1 ; 前景色为蓝色,背景色为白色
mov cl, 15
mov si, offset data
call show_line
pop cx
pop si
pop es
pop bx
pop ax
ret
show_line:
push ax
push bx
; 计算字符串长度
mov cx, 0
mov bx, si
calc_length:
mov al, [si]
cmp al, 0
je done_calc_length
inc cx
inc si
jmp calc_length
done_calc_length:
mov si, bx
; 计算偏移量
mov bx, 0
mov ax, 160
mul dh
add bx, ax
mov ax, 2
mul dl
add bx, ax
mov ax, cx
sub ax, 1
shr ax, 1
mov dx, 80
sub dx, ax
mov bx, [bx]
add bx, dx
; 显示字符串
mov si, offset data
show_char:
lodsb
cmp al, 0
je done_show_line
mov ah, cl
stosw
jmp show_char
done_show_line:
pop bx
pop ax
ret
```
在 `show_str` 中,我们先使用 `show_line` 函数分别显示绿色、绿底红色、白底蓝色的字符串。这里我们将计算字符串长度和偏移量的部分提取出来,单独写了一个 `show_line` 函数。在 `show_line` 中,我们先计算字符串长度,然后计算偏移量,最后在屏幕上显示字符串。
需要注意的是,我们在 `show_str` 中调用了三次 `show_line` 函数,每次需要设置不同的前景色和背景色。在 `show_line` 中,我们使用 `ah` 存储前景色,使用 `cl` 存储背景色。在显示绿色字符串时,我们将 `al` 设置为 2,表示前景色为绿色,背景色为黑色。在显示绿底红色字符串时,我们将 `al` 设置为 4,表示前景色为红色,背景色为绿色。在显示白底蓝色字符串时,我们将 `al` 设置为 1,表示前景色为蓝色,背景色为白色。
完整的代码如下:
```
assume cs:code, ds:data
data segment
db 'welcome to masm!',0
data ends
code segment
start:
mov dh, 8
mov dl, 3
mov cl, 2
mov ax, data
mov ds, ax
mov si, 0
call show_str
mov ax, 4c00h
int 21h
show_str:
push ax
push bx
push es
push si
push cx
; 显示绿色字符串
mov ax, 0B800h
mov es, ax
mov ax, 160
mul dh
mov bx, ax
mov ax, 2
mul dl
add bx, ax
mov al, 2 ; 前景色为绿色
mov cl, 0 ; 背景色为黑色
mov si, offset data
call show_line
; 显示绿底红色字符串
mov ax, 0B800h
mov es, ax
mov ax, 160
mul dh
mov bx, ax
mov ax, 2
mul dl
add bx, ax
mov al, 4 ; 前景色为红色,背景色为绿色
mov cl, 2
mov si, offset data
call show_line
; 显示白底蓝色字符串
mov ax, 0B800h
mov es, ax
mov ax, 160
mul dh
mov bx, ax
mov ax, 2
mul dl
add bx, ax
mov al, 1 ; 前景色为蓝色,背景色为白色
mov cl, 15
mov si, offset data
call show_line
pop cx
pop si
pop es
pop bx
pop ax
ret
show_line:
push ax
push bx
; 计算字符串长度
mov cx, 0
mov bx, si
calc_length:
mov al, [si]
cmp al, 0
je done_calc_length
inc cx
inc si
jmp calc_length
done_calc_length:
mov si, bx
; 计算偏移量
mov bx, 0
mov ax, 160
mul dh
add bx, ax
mov ax, 2
mul dl
add bx, ax
mov ax, cx
sub ax, 1
shr ax, 1
mov dx, 80
sub dx, ax
mov bx, [bx]
add bx, dx
; 显示字符串
mov si, offset data
show_char:
lodsb
cmp al, 0
je done_show_line
mov ah, cl
stosw
jmp show_char
done_show_line:
pop bx
pop ax
ret
code ends
end start
```