检测点10.4
下面的程序运行后,ax中的数值是多少?
内存地址 机器码 汇编指令
1000:0 b8 06 00 mov ax,6
1000:2 ff d0 call ax
1000:5 40 inc ax
1000:6 mov bp, sp
mov ax,[bp]
分析:
call ax载入cpu后,cpu先将ip+3=5,然后执行call ax;
执行call ax时,先push ip(ss:[sp]=5),再将ip设为6,即程序跳到1000:6继续执行;
mov bp,sp将sp的值送入bp
此时bp的值与sp一样,并且bp的默认段寄存器是ss,因此此句此时等同于ss:[sp],指向栈顶,而栈顶此时的值为5
检测点10.5
下面的程序执行后,ax的值是多少?
assume cs:code
stack segment
dw 8 dup(0)
stack ends
code segment
start:
mov ax, stack
mov ss, ax
mov sp, 16 ;以上三句初始化栈
mov ds, ax ;将数据段和栈段的段地址设为同一值
mov ax, 0
call word ptr ds:[0EH] ;cpu载入此句后,先将ip+3使ip指向下一句inc ax的偏移地址(假设为0081h)
;然后执行此句,先push ip,然后jmp word ptr ds:[0eh]
;push ip时先将sp-2=0eh,再将ip的值0081h放入0eh
;执行jmp word ptr ds:[0eh]时由于ds=ss,相当于执行jmp word ptr ss:[0eh],而ss:[0eh]等于0081h
;另外0081h是inc ax的地址,因此程序跳到inc ax继续执行
;在连续执行三个inc ax后ax=3
inc ax
inc ax
inc ax
code ends
end start
实验室11
编写一个子程序,将包含任意字符,以0结尾的字符串中的小写字母转变成大写字母。注意需要进行转化的是字符串中的小写字母a-z,而不是其它字符
assume cs:code,ds:data
data segment
db "Beginner's All-purpose Symbolic Instruction Code.",0
data ends
code segment
start: mov ax,data
mov ds,ax
mov si,0
call letterc
mov ax,40cch
int 21h
letterc:mov bl,ds:[si]
cmp bl,0
jne s
ret
s: mov di,si7BH
inc si
cmp bl,61h
jb letterc
cmp bl,7ah
ja letterc
and bl,11011111b
mov ds:[di], bl
jmp letterc
code ends
end start
这里需要注意第27行,为什么小写字母按位与11011111b后就会变成相应的大写字母?
首先,这个只是观察后发现的规律而已,不是我要注解的。我只是想指出进行此步操作时可能出现的误区,下面以a转A为例说明:
误区一:有人查ascii得出a的ascii码的16进制表示为61h,A的是41h。而在转化为二进制时却把这两个16进制数当成了10进制数,因而得出61h=00111101,41h=00101001h
误区二:书中所谓的第5位实际是从右到左的第6位,因为索引是从0开始的