【汇编语言】第 10 章 CALL 和 RET 指令

版权声明:本文为 gfson 原创文章,转载请注明出处。
注:作者水平有限,文中如有不恰当之处,请予以指正,万分感谢。

10.1 ret 和 retf

10.2 检测点 10.1

  • 答案:
  • 1000h
  • 0

10.3 call 指令

call 指令的种类:

  • call 标号
  • call far ptr 标号
  • call 16 位 reg
  • call word ptr 内存单元地址
  • call dword ptr 内存单元地址

10.4 检测点 10.2 - 10.5

  • 答案:

ax 中的数值为 6,注意执行完 call s 后,IP 先变为 6,然后将 IP 的值压栈,最后跳转至 s。

  • 答案:

ax 中的数值为 1010H,注意执行完 call far ptr s 后,IP 先变为 8,然后将 CS、IP 的值分别为 1000 和 8 依此压栈,最后再跳转至 s 继续执行。

  • 答案:

ax 中的数值为 0BH。

  • 答案:

(1)

  • ax 中的数值为 3,注意 ds 与 ss 中存放的段地址相同,在执行了 call word ptr ds:[0EH] 之后,程序会先将下一条指令 inc ax 的偏移量压栈,然后跳转到栈顶所指向的指令的位置,即跳转至第一条 inc ax 的位置,故最后 ax 的值为 3。
  • 注意 :在使用 Debug 单步跟踪的时候,由于 t 命令所导致的中断,而影响了栈中的值。

(2)

  • ax 中的数值为 1,bx 中的数值为 0,注意到程序的一开始将 a 的偏移量和 cs 放入 ss:[0] 和 ss:[2] 中,然后调用 call 指令,将 CS 和 IP(nop 指令的偏移量)依此压栈后跳转到 s 处继续执行,ax 最终为 s 的偏移量减去 nop 指令所在位置的偏移量,为 1,bx 最终为 cs 的段地址相减,为 0。

10.5 call 和 ret 的配合

利用 call 和 ret 的配合来实现子程序机制

10.6 mul 指令

10.7 子程序模板

10.8 实验 10

实验题目篇幅太长,此处不予摘录,请参考原书。

答案

  • 显示字符串
assume cs:code, ss:stack
stack segment
dw 16 dup (0)
stack ends
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 ax, stack
mov ss, ax
mov sp, 32
mov si, 0
call show_str
mov ax, 4c00h
int 21h
show_str:
push cx
push bx
push ax
push si
push di
push es
;using cx, bx, ax, si, di, es
mov ax, 0b800h
mov es, ax
mov bx, 0
mov di, 0
mov al, 160
mul dh
add bx, ax
mov al, 2
mul dl
add bx, ax ;bx stores address of start character
mov al, cl ;al stores the color of character
char:   mov ch, 0
mov cl, ds:[si]
jcxz zero
mov ch, al
mov es:[bx+di], cx
add di, 2
inc si
jmp char
zero:   pop es
pop di
pop si
pop ax
pop bx
pop cx
ret
code ends
end start
  • 解决除法溢出的问题
assume cs:code, ss:stack
stack segment
dw 16 dup (0)
stack ends
code segment
start:  mov ax, stack
mov ss, ax
mov sp, 32
mov ax, 4240h
mov dx, 000fh
mov cx, 0ah
call divdw
mov ax, 4c00h
int 21h
divdw:  push bx
mov bx, ax ; bx stores L
mov ax, dx ; ax stores H
mov dx, 0
div cx ; after div, ax holds int(H/N), dx holds rem(H/N)
push ax ; push int(H/N) temporarily
mov ax, bx ; ax stores L
div cx
mov cx, dx
pop dx
pop bx
ret
code ends
end start
  • 数值显示
assume cs:code, ss:stack
stack segment
dw 16 dup (0)
stack ends
data segment
db 10 dup (0)
data ends
code segment
start:  mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 32
mov ax, 12666
mov si, 0
call dtoc
mov dh, 8
mov dl, 3
mov cl, 2
call show_str
mov ax, 4c00h
int 21h
dtoc:   push ax
push si
push di
push dx
push bx
push cx
mov di, 0
mov dx, 0
mov bx, 10
devide: mov cx, ax
jcxz stop
div bx
inc di
push dx
mov dx, 0
jmp devide
stop:   mov cx, di
string: pop bx
add bx, 30h
mov [si], bl
inc si
loop string
pop cx
pop bx
pop dx
pop di
pop si
pop ax
ret
show_str:
push cx
push bx
push ax
push si
push di
push es
;using cx, bx, ax, si, di, es
mov ax, 0b800h
mov es, ax
mov bx, 0
mov di, 0
mov al, 160
mul dh
add bx, ax
mov al, 2
mul dl
add bx, ax ;bx stores address of start character
mov al, cl ;al stores the color of character
char:   mov ch, 0
mov cl, ds:[si]
jcxz zero
mov ch, al
mov es:[bx+di], cx
add di, 2
inc si
jmp char
zero:   pop es
pop di
pop si
pop ax
pop bx
pop cx
ret
code ends
end start

10.9 课程设计 1

课程设计 1 要求请参考原书。

  • 答案:
;注:函数中的标号为防止冲突,都加了本函数名为前缀
;在Debug中输入“-g 90”,直接运行到结束
assume cs:code
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
;以上是表示21年的21个字符串
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;以上是表示21年公司总收的21个dword型数据
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,45257,17800
;以上是表示21年公司雇员人数的21个word型数据
data ends
agency segment
db 8 dup(0)
agency ends

code segment
start: mov ax,0b800h
mov es,ax
mov di,0
mov cx,80*24
x: mov byte ptr es:[di],' ' ;将屏幕清空
mov byte ptr es:[di+1],0
inc di
inc di
loop x
mov ax,data
mov es,ax
mov di,0
mov bx,0
mov ax,agency
mov ds,ax
mov si,0
mov dh,4
mov cx,21
x1: push cx
mov ax,es:[di]
mov ds:[si],ax
mov ax,es:[di+2]
mov ds:[si+2],ax
mov byte ptr ds:[si+4],0 ;显示年份
mov dl,0
mov cl,2
call show_str
mov ax,es:[84+di]
push dx
mov dx,es:[84+di+2]
call dtoc_dword ;显示收入
pop dx
mov dl,20
mov cl,2
call show_str

mov ax,es:[84+84+bx]
call dtoc_word
mov dl,40 ;显示雇员数
mov cl,2
call show_str

mov ax,es:[84+di]
push dx
mov dx,es:[84+di+2]
div word ptr es:[84+84+bx] ;计算人均收入并显示
call dtoc_word
pop dx
mov dl,60
mov cl,2
call show_str

add di,4
add bx,2
add dh,1
pop cx
loop x1
mov ax,4c00h
int 21h

;名称:show_str
;功能:在屏幕的指定位置,用指定颜色,显示一个用0结尾的字符串
;参数:(dh)=行号,(dl)=列号(取值范围0~80),(cl)=颜色,ds:si:该字符串的首地址
;返回:显示在屏幕上
show_str:
push ax
push cx
push dx
push es
push si
push di
mov ax,0b800h
mov es,ax
mov al,160
mul dh
add dl,dl
mov dh,0
add ax,dx
mov di,ax
mov ah,cl
show_str_x:
mov cl,ds:[si]
mov ch,0
jcxz show_str_f
mov al,cl
mov es:[di],ax
inc si
inc di
inc di
jmp show_str_x
show_str_f:
pop di
pop si
pop es
pop dx
pop cx
pop ax
ret
;名称:dtoc_word
;功能:将一个word型数转化为字符串
;参数:(ax)=word型的数据,ds:si指向字符串的首地址
;返回:ds:[si]放此字符串,以0结尾
dtoc_word:
push ax
push bx
push cx
push dx
push si
mov bx,0
dtoc_word_x:
mov dx,0
mov cx,10
div cx
mov cx,ax
add dx,'0'
push dx
inc bx
jcxz dtoc_word_f
jmp dtoc_word_x
dtoc_word_f:
mov cx,bx
dtoc_word_x1:
pop ds:[si]
inc si
loop dtoc_word_x1
pop si
pop dx
pop cx
pop bx
pop ax
ret
;名称:dtoc_dword
;功能:将一个double word型数转化为字符串
;参数:(dx)=数的高八位,(ax)=数的低八位
;返回:ds:[si]放此字符串,以0结尾
;备注:会用到divdw函数
dtoc_dword:
push ax
push bx
push cx
push dx
push si
mov bx,0
dtoc_dword_x:
mov cx,10
call divdw
push cx
inc bx
cmp ax,0
jne dtoc_dword_x
cmp dx,0
jne dtoc_dword_x
mov cx,bx
dtoc_dword_x1:
pop ds:[si]
add byte ptr ds:[si],'0'
inc si
loop dtoc_dword_x1
pop si
pop dx
pop cx
pop bx
pop ax
ret
;名称:divdw
;功能:除法,被除数32位,除数16位,商32位,余数16位,不会溢出
;参数:(dx)=被除数高16位,(ax)=被除数低16位,(cx)=除数
;返回:(dx)=商高16位,(ax)=商低16位,(cx)=余数
divdw:
push bx
push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax
pop ax
div cx
mov cx,dx
mov dx,bx
pop bx
ret

code ends
end start
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容

  • 8086汇编 本笔记是笔者观看小甲鱼老师(鱼C论坛)《零基础入门学习汇编语言》系列视频的笔记,在此感谢他和像他一样...
    Gibbs基阅读 37,140评论 8 114
  • 计算机通过执行指令序列来使机器得以工作,所以对于每一系列的计算机都有指定的一组指令集供计算机使用,这组指令...
    未来科技工作室阅读 7,955评论 1 10
  • 指令是使计算机执行某种特定操作的二进制编码。8086 CPU指令系统有133条指令,通常分为数据寻址方式和程序寻址...
    刀月水阅读 1,626评论 0 1
  • 王爽汇编全书知识点大纲 第一章 基础知识 机器语言 汇编语言的产生 汇编语言的组成 存储器 cpu对存储器的读写 ...
    2c3ba901516f阅读 2,408评论 0 1
  • 以前,我常说人可以在潜意识或情绪发生过程中,用意识去感知潜意识的存在,一旦成功,就能实现意识对潜意识的干预,不论是...
    adamant555阅读 441评论 0 0