1、安装汇编语言开发环境,能够利用作者提供的库函数显示寄存器的内容和标志位状态。 2、 编写简单的程序,能够定义不同类型的数据:字节、字、双字,熟悉开发环境,并能够利用调试工具 OllyDBG 调试程序,能利用 OllyDBG 观察寄存器和内存空间的变化。 3、 在内存中定义如下数据: Var1 byte 56h,78h,90h,0abh Var2 word 5678h,7890h,8000h,9356h,0BF87hVar3 dword 4 dup(?) Var4 dword 5 dup(?) 编写程序完成如下功能:以字节为单位:var1 + [var1+1],并观察寄存器和标志位变化; 以字为单位: var1 + [var1+2] ,并观察寄存器和标志位变化 以字为单位: var2 – var1,并观察寄存器和标志位变化 Var2 + [var2+2],并观察寄存器和标志位变化 Var2 - [var2+2],并观察寄存器和标志位变化 Var2 + [var2+4] ,并观察寄存器和标志位变化 Var2 - [var2+4] ,并观察寄存器和标志位变化 [var2+4] + [var2+8],并观察寄存器和标志位变化 [var2+4] - [var2+8],并观察寄存器和标志位变化 编写一个循环,将 var1 中的四个元素,进行符号扩展成双字后,传递到 var3,观察存储 器的变化编写一个玄幻,将 var2 中的 5 个元素,进行零扩展成双字后,倒序传送到 var4,即 var2 中的最后一个元素传递到 var4 的第一个元素,var2 中的第一个元素,传递到 var4 的最 后一个元素 注:后面两个循环需要利用间接寻址方式。 4、 请利用第五章中作者提供的库函数 DumpMem,将上题中最终的 var1,var2,var3,var4 的内 容显示出来。 5、 使(EAX)=30313233h,调用函数 WriteChar,将 EAX 中的每一个字节以 ASCII 的形式显 示在屏幕上。 使(EAX)=56789012h 如果把 AH 寄存器中的值看作无符号数,是多少,并调用 WriteDec 函数将 AH 的值显示 在屏幕上。如果把 AH 寄存器中的值看作带符号数,是多少,并调用 WriteInt 函数将 AH 的值显示在 屏幕上。 定义一个字符串“Welcome to AssembleLanguage!”,并调用WriteString 函数,将字符串 显示在屏幕上。
代码如下(仅供参考):
1.
.code
main PROC
callDumpRegs ;显示寄存器的内容和标志位状态。
exit
main ENDP
3.
.data
var1 byte 56h,78h,90h,0abh
var2 word 5678h,7890h,8000h,9356h,0BF87h
var3 dword 4 dup(?)
var4 dword 5 dup(?)
.code
main PROC
moval,var1
inc al
addal,var1
callDumpRegs ;以字节为单位:var1 +[var1+1],并观察寄存器和标志位变化;
movdx,WORD PTR var1
add ax,dx
add ax,2
add ax,dx
callDumpRegs ;以字为单位: var1 + [var1+2] ,并观察寄存器和标志位变化
mov ax,var2
sub ax,dx
callDumpRegs ;以字为单位: var2 – var1,并观察寄存器和标志位变化
mov ax,var2
add ax,2
addax,var2
callDumpRegs ;var2 +[var2+2],并观察寄存器和标志位变化
mov dx,var2
add dx,2
movax,var2
sub ax,dx
callDumpRegs ;var2 -[var2+2],并观察寄存器和标志位变化
mov ax,var2
add ax,4
addax,var2
callDumpRegs ;var2 +[var2+4] ,并观察寄存器和标志位变化
mov dx,var2
add dx,4
movax,var2
sub ax,dx
callDumpRegs;var2 -[var2+4] ,并观察寄存器和标志位变化
mov dx,var2
add dx,8
movax,var2
add ax,4
add ax,bx
callDumpRegs;[var2+4] +[var2+8],并观察寄存器和标志位变化
mov dx,var2
add dx,8
movax,var2
add ax,4
sub ax,bx
callDumpRegs;[var2+4] -[var2+8],并观察寄存器和标志位变化
mov ecx,4;循环计数器
movesi,0 ;var1地址偏移
movedx,0 ;var3地址偏移
L1:
movsxeax,[var1+esi];符号扩展
mov[var3+edx],eax
inc esi
add edx,4;根据数据大小移动
Loop L1
callDumpRegs ;观察存储器的变化
mov ecx,5;循环计数器
movedx,16 ;反向移动
mov esi,0;正向移动
L2:
movsxeax,[var2+esi]
mov[var4+edx],eax
add esi,2
sub edx,4
Loop L2
callDumpRegs ;观察存储器的变化
exit
main ENDP
END main
4.
.data
var1 byte 56h,78h,90h,0abh
var2 word 5678h,7890h,8000h,9356h,0BF87h
var3 dword 4 dup(?)
var4 dword 5 dup(?)
.code
main PROC
mov ecx,4;循环计数器
movesi,0
movedx,0
L1:
movsxeax,[var1+esi]
mov[var3+edx],eax
inc esi
add edx,4
Loop L1
callDumpRegs
mov ecx,5;循环计数器
movedx,16
mov esi,0
L2:
movsxeax,[var2+esi]
mov[var4+edx],eax
add esi,2
sub edx,4
Loop L2
callDumpRegs ;以上程序与上一题相同
movesi,OFFSET var1
movebx,TYPE var1
movecx,LENGTHOF var1 ;循环计数器
call DumpMem ;显示var1
movesi,OFFSET var2
movebx,TYPE var2
movecx,LENGTHOF var2 ;循环计数器
call DumpMem ;显示var2
movesi,OFFSET var3
movebx,TYPE var3
movecx,LENGTHOF var3 ;循环计数器
call DumpMem ;显示var3
movesi,OFFSET var4
movebx,TYPE var4
movecx,LENGTHOF var4 ;循环计数器
call DumpMem ;显示var4
exit
main ENDP
END main
5.
.code
main PROC
mov(eax),30313233h ;(EAX)=30313233h
mov ecx,4;循环计数器
L1:
callWriteChar
shr eax,8
LoopL1 ;将 EAX 中的每一个字节以 ASCII的形式显示在屏幕上
exit
main ENDP
END main
.code
main PROC
mov(eax),56789012h;(EAX)=56789012h
movzxeax,ah;零扩展
callWriteDec
mov(eax),56789012h
movsxeax,ah;符号扩展
callWriteInt
exit
main ENDP
END main
.data
source BYTE "Welcome to AssembleLanguage" ;定义一个字符串
.code
main PROC
mov edx,OFFSET source
callWriteString ;将字符串 显示在屏幕上。
exit
main ENDP
END main
1、编写程序求 EDX:EAX 中 64 位数据的绝对值,并将结果以十进制数的形式显示出来(第二步选做)。
2、假设内存中已经建立好了一个数字 1~10 的平方表,如:1 4 916 25 36 49 64 81 100 根据从键盘输入数字,根据数字查找该表,并将结果显示,如在键盘输入数字 5,则显示25。(要求:将查找功能用函数实现,至少要将数组名、要查找的元素作为参数传入该函数;使用显示的堆栈调用,同时调用教材作者提供的WriteStackFrame 函数将堆栈的内容显示出来。)
3、假设 C++语言中,有如下代码,换为汇编语言代码。
int sub1(int x1,int y1)
{
int a,b;
a=x1;
b=y1;
if((a>b)&&(a>0))
{
y1=x1;
return y1;
}
else
{
x1=y1;
return x1;
}
}
int main()
{
inta,b;
a=25;
b=-35;
sub1(a,b);
}
代码如下(仅供参考):1、.code
main PROC
mov edx, -30
moveax, 0h
cmpedx, 0 ;检测一下是否为正,若是直接跳转进行输出
jGL1
notedx ;不是正数要进行取反加1,变为正数
noteax
addeax,1
jncL1 ;adc edx,1
addedx,1
L1:
pusheax
pushedx
popeax
callWriteDec ;十进制输出
callDumpRegs ;显示register内容
exit
main ENDP
END main
2、.data
num Byte 1,4,9,16,25,36,49,64,81,100
.code
find Proc
pushebp ;ebp压栈
movebp, esp ;栈顶指针esp指为ebp
pusheax
pushedx
PARAMS= 2
LOCALS= 0
SAVED_REGS= 3
movedx,[ebp+8] ; edx 为 x
subedx,1 ; edx 为 edx - 1
moveax,[ebp+12] ; eax 为num
moval,[eax + edx] ; al 为 num[edx]
movzxeax,al ; 将al零扩展到32位给eax寄存器
callWriteDec ; 以十进制输出
invokeWriteStackFrame, PARAMS, LOCALS, SAVED_REGS ;追踪堆栈现在情况
popedx
popeax
movesp, ebp
popebp
ret8 ;释放
find endp
main PROC
push offset num
callReadDec ;从屏幕读入一个数
pusheax
callfind
exit
main ENDP
END main
3..data
a sdword ? ;定义有符号数
b sdword ?
.code
sub1 PROC
mova,eax ;a=x1
movb,ebx ;b=y1
cmpa,ebx
jleL1
cmpa,0
jleL1
movebx,a ; y1=x1
jmpL2
L1:
mov eax,b ; x1=y1
jmp L2
L2:
ret
sub1 ENDP
main PROC
mov eax,25 ;将参数传入函数
mov ebx,-35
call sub1 ;调用函数
exit
main ENDP
END main