10.1补全程序,实现从内存1000:0000处开始执行指令
assume cs:code
stack segment
db 16 dup (0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,01000h
push ax
mov ax,0
push ax
retf
code ends
end start
10.2下面的程序执行后,ax中的数值为多少?
内存地址 机器码 汇编指令 执行后情况
1000:0 b8 00 00 mov ax,0 ax=0 ip指向1000:3
1000:3 e8 01 00 call s ax=0 ip指向1000:6
1000:6 40 inc ax
1000:7 58 s:pop ax ax=6
10.3下面的程序执行后,ax中的数值为多少?
内存地址 机器码 汇编指令 执行后情况
1000:0 b8 00 00 mov ax,0 ax=0,ip指向1000:3
1000:3 9a 09 00 00 10 call far ptr s ip指向1000:8,push cs,push ip,ip指向1000:9
1000:8 40 inc ax
1000:9 58 s:pop ax ax=8h
add ax,ax ax=10h
pop bx bx=1000h
add ax,bx ax=1010h
10.4下面的程序执行后,ax中的数值为多少?
内存地址 机器码 汇编指令 执行后情况
1000:0 b8 06 00 mov ax,6 ax=6,ip指向1000:3
1000:3 ff d0 call ax ip指向1000:5,push ip,ip指向1000:6
1000:5 40 inc ax
1000:6 58 mov bp,sp
add ax,[bp] ax=0bh
“call 16位寄存器”这条指令相当于进行如下的操作: push ip , jmp 16位寄存器。所以有先把sp的值减去二,然后把0005入栈,接着是jmp ax即把ax的值去修改ip的值,执行完call ax之后,ip的值为6。因为现在sp的值是指向存放0005的下一个内存单元,比如原来sp的值是10h,sp先减去2,然后把0005压入栈内。这里吧sp送给bp,则内存单元[bp]代表的就是ss:[bp]这个单元。所以add ax,[bp]就是把刚压入栈的值0005加上ax的值后送给ax。最后ax为5+6=11即0bh。
10.5.1 下面的程序执行后,ax中的数值为多少?(注意用call指令的原理来分析,不要在Debug中单步跟踪来验证你的结论。对于此程序,在Debug中单步跟踪的结果,不能代表CPU的实际执行结果)
assume cs:codesg
stack segment
dw 8 dup (0)
stack ends
codesg segment
start:
mov ax,stack
mov ss,ax
mov sp,16
mov ds,ax
mov ax,0
call word ptr ds:[0EH]
inc ax
inc ax
inc ax
mov ax,4c00h
int 21h
codesg ends
end start
call word ptr ds:[0EH]
执行的时候,将第一个inc ax
的ip入栈,然后跳转到ds:[0EH]
中继续执行,而ds:[0EH]
中的值正好是第一个inc ax
的ip。所以 ax=3
10.5.2 下面的程序执行后 , ax 和 bx 的值是什么 ?
assume cs:code,ds:data
data segment
dw 8 dup(0)
data ends
code segment
start:
mov ax, data
mov ss, ax
mov sp, 16
mov word ptr ss:[0], offset second
mov ss:[2], cs
call dword ptr ss:[0]
nop
second:
mov ax, offset second
sub ax, ss:[0CH]
mov bx, cs
sub bx, ss:[0EH]
code ends
end start
都是0