检测点10.4
下面的程序运行后,ax中的数值是多少?
内存地址 机器码 汇编指令
1000:0 b8 06 00 mov ax,6
1000:2 ff d0call ax
1000:5 40inc ax
1000:6mov 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开始的