一、实验目的
assume cs:code
data segment
db ‘welcome to masm!‘
db 2,36,113
data ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,0b86eH
mov es,ax
mov bx,0
mov cx,3
s1: push cx
mov cx,16
mov si,0
mov di,64
s: mov al,[si]
mov es:[di],al
mov al,[16+bx]
mov es:[di+1],al
inc si
add di,2
loop s
inc bx
mov ax,es
add ax,0ah
mov es,ax
pop cx
loop s1
mov ax,4c00h
int 21h
code ends
end start
运行结果:
先将‘welcome to masm!‘存入data段所代表的内存空间,然后计算出需要显示的颜色的10进制数据放在‘welcome to masm!‘后面方便取数据时直接取出颜色属性。
代码段code:
将data的地址赋值给ds段寄存器,数据段寄存器指向目标数据存放的内存空间。
计算屏幕中间上一排对应的段地址为0b86eh,并将其赋值给额外的数据段寄存器es
mov bx,0 用bx记录当前输出行数
mov cx,3 需要输出三行,外层循环为3次
需要嵌套使用loop指令因此在执行显示时将当前cx压入栈,并标记为s1
内存循环:共16个字符,因此循环16次
计算输出到中间列的起始列偏移量为64,因此mov di,64,并将字符赋值到es:[di]
对应的颜色属性为[16+bx],将其赋值到es:[di+1]
一行输出结束后,进入下一行,将es+0ah
pop cx将cx值出栈进入下一循环显示下一行的数据。
2.实验任务2
assume cs:code, ds:data data segment str db ‘try‘, 0 data ends code segment start: mov ax, data mov ds, ax mov si, offset str mov al, 2 call printStr mov ah, 4ch int 21h printStr: push bx push cx push si push di mov bx, 0b800H mov es, bx mov di, 0 s: mov cl, [si] mov ch, 0 jcxz over mov ch, al mov es:[di], cx inc si add di, 2 jmp s over: pop di pop si pop cx pop bx ret code ends end start
实验结果:
对程序做如下修改:
把line3改为: str db ‘another try‘, 0
把line12改为:mov al, 4
结果:
line19-22, line36-39,这组对称使用的push、pop,这样用的目的用于保存和恢复寄存器的值。在用寄存器前先将寄存器的值入栈,保留原本寄存器的内容,使用完后出栈恢复寄存器里的内容,防止出现意外情况。line30的功能是设置字符颜色属性。
3.实验任务3
assume cs:code, ds:data data segment x dw 1984 str db 16 dup(0) data ends code segment start: mov ax, data mov ds, ax mov ax, x mov di, offset str call num2str mov ah, 4ch int 21h num2str: push ax push bx push cx push dx mov cx, 0 mov bl, 10 s1: div bl inc cx mov dl, ah push dx mov ah, 0 cmp al, 0 jne s1 s2: pop dx or dl, 30h mov [di], dl inc di loop s2 pop dx pop cx pop bx pop ax ret code ends end start
对3.asm进行汇编、链接,得到可执行程序后,在debug中使用u命令反汇编,使用g命令执行到line15(程序退出之前),使用d命令查看数据段内容,观察是否把转换后的数字字符串‘1984‘存放在数据段中str标号后面的单元。
结果:
对3.asm源代码进行修改、完善,把2.asm中用于输出以0结尾的字符串的子程序加进来,实现对转换后的字符串进行输出。
assume cs:code, ds:data data segment x dw 1984 str db 16 dup(0) data ends code segment start: mov ax, data mov ds, ax mov ax, x mov di, offset str call num2str mov si, offset str call printfstr mov ah, 4ch int 21h num2str: push ax push bx push cx push dx mov cx, 0 mov bl, 10 s1: div bl inc cx mov dl, ah push dx mov ah, 0 cmp al, 0 jne s1 s2: pop dx or dl, 30h mov [di], dl inc di loop s2 pop dx pop cx pop bx pop ax ret printfstr: push ax push bx push cx push si push di mov ax,2 mov bx,0b800H mov es,bx mov di,0 s: mov cl,[si] mov ch,0 jcxz over mov ch,al mov es:[di],cx inc si add di,2 jmp s over: pop di pop si pop cx pop bx pop ax ret code ends end start
实验结果:
line3中整数改成0~2559之间的任意数值,运行测试,观察结果
4.实验任务4
使用任意文本编辑器,录入汇编源程序
assume cs:code, ds:data data segment str db 80 dup(?) data ends code segment start: mov ax, data mov ds, ax mov si, 0 s1: mov ah, 1 int 21h mov [si], al cmp al, ‘#‘ je next inc si jmp s1 next: mov cx, si mov si, 0 s2: mov ah, 2 mov dl, [si] int 21h inc si loop s2 mov ah, 4ch int 21h code ends end start
#include <stdio.h> int sum(int, int); int main() { int a = 2, b = 7, c; c = sum(a, b); return 0; } int sum(int x, int y) { return (x + y); }
高级语言中参数传递,从汇编的角度是如何传递的,返回值是如何返回的;多个参数的入栈顺序是什么样的;函数调用栈
c = sum(a, b);
000918A6 mov eax,dword ptr [b]
000918A9 push eax 在调用sum函数之前将b指向的数据放入寄存器eax中并且保存进栈中
000918AA mov ecx,dword ptr [a]
000918AD push ecx 然后保存a指向的内存单元的数据到栈中并且放入寄存器ecx中
000918AE call sum (091096h) 调用sum函数
000918B3 add esp,8
000918B6 mov dword ptr [c],eax 将结果赋值给c指向的内存单元 说明返回值在eax中
return (x + y);
00091828 mov eax,dword ptr [x] 将x指向的内存单元的数据移入寄存器eax中
0009182B add eax,dword ptr [y] 将y指向的内存单元的数据和eax中的数据相加后放入寄存器eax中
原文:https://www.cnblogs.com/yu136/p/14152230.html