|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
ReadAsm编写
- .386
- .model flat,stdcall
- option casemap:none
-
- include masm32rt.inc
-
-
- .data
- ; ========= 结构体 =========
- ;电话本-成员
- PHONE struct
- m_name byte 8 dup(0) ;姓名
- m_phone byte 8 dup(0) ;电话
- PHONE ends
-
- ; ========= 常量 =========
- ;输入格式:名称 电话号码
- g_szScanFormat BYTE '%s %s',0h
- ;输入格式:名称
- g_szScanNameFormat BYTE '%s',0h
- ;打印格式:名称\t\t电话号
- g_szPrintItemFormat BYTE '姓名:%s',09h,09h,'电话:%s',0ah,0dh,0h
- ;输入指令
- g_szGetCmdFormat BYTE '%d',0h
-
- ;菜单
- g_szMenu db "电话本",0ah,0dh,
- "1=查询",0ah,0dh,
- "2=增加",0ah,0dh,
- "3=删除",0ah,0dh,
- "4=修改",0ah,0dh,
- "5=查看所有",0ah,0dh,
- "当前储存了 %d / %d 条信息",0ah,0dh,
- ">>",0h
-
- g_szClr BYTE 'cls',0h
- g_szPause BYTE 'pause',0h
- g_szCmdIn BYTE '%d',0h
- g_szNameIn BYTE '输入姓名:',0h
- g_szNewNameIn BYTE '输入新的姓名:',0h
- g_szPhoneNumberIn BYTE '请输入电话号码:',0h
- g_szNewPhoneNumberIn BYTE '请输入新的电话号码:',0h
- g_szTab BYTE 0dh,0ah,0h ;换行回车\r\n
- g_szTipsDel BYTE '<已删除这条信息>',0dh,0ah,0h
- g_szTipsAdd BYTE '<插入成功>',0dh,0ah,0h
- g_szTipsUpdate BYTE '<修改成功>',0dh,0ah,0h
- g_szTipsNoMore BYTE '<没有更多信息>',0dh,0ah,0h
- g_szErrNotFind BYTE '<没有这条信息>',0dh,0ah,0h
- g_szErrMax BYTE '<电话本储存满了>',0dh,0ah,0h
- g_szErrUnknowCmd BYTE '<未知指令>',0dh,0ah,0h
-
- ; ========= 全局变量 =========
- ;电话本
- g_book PHONE 20 dup(<'0'>)
- ;最大容量 最多保存20条记录
- g_max dword 1 dup(20)
- ;当前容量
- g_nCount dword 1 dup(0)
- ;单个电话本临时变量
- g_tmpPhone PHONE <'0','0'>
- ;当前用户选择的功能 1=查询 2=增加 3=删除 4=修改 5=看所有
- g_nCmd byte 1 dup(0)
- ;索引查找数
- g_nI dword 1 dup(0)
- ;临时指针
- g_nTmp dword 1 dup(0)
- ;找到了的索引
- g_nFindIndex dword 1 dup(-1)
- ;找到了的地址
- g_nFindPoint dword 1 dup(0)
-
-
- .code
-
- ; 打印菜单并接收用户指令到eax
- ; 功能 1=查询 2=增加 3=删除 4=修改
- SelectMenu proc
- ; 清屏
- push offset g_szClr
- call crt_system
- add esp,4
- ; 打印菜单
- push g_max
- push g_nCount
- push offset g_szMenu
- call crt_printf
- add esp,12
- ; 用户输入指令,放入g_nCmd
- push offset g_nCmd
- push offset g_szCmdIn
- call crt_scanf
- add esp,8
- ret
-
- SelectMenu endp
-
- ; 查找用户
- PhoneFind proc
- ; 提示输入姓名
- push offset g_szNameIn
- call crt_printf
- add esp,4
- ; 用户输入姓名
- lea eax,[g_tmpPhone + PHONE.m_name]
- push eax
- push offset g_szScanNameFormat
- call crt_scanf
- add esp,8
- ; 重置i
- mov g_nI,0 ; i = 0
- find_loop:
- mov eax,g_nI
- mov ebx,g_max ; max
- cmp eax,ebx
- ja find_empty ;i > g_max ,goto proc_end
- ; 计算地址
- imul eax,g_nI,sizeof(PHONE) ; i*单个元素大小 = 偏移地址给edi
- lea edi,[g_book + eax] ; 电话本首地址 + 偏移地址 = 第i个元素的地址
- lea edx,[edi] ; 保存第i个元素地址
- mov g_nTmp, edx
- ; 判断这个元素的姓名和输入的姓名是否匹配
- lea esi,[g_tmpPhone + PHONE.m_name]
- cmpsd dword ptr[edi + PHONE.m_name],dword ptr[esi]
- jnz not_find
- ; 找到了就输出信息
- lea eax, [edx + PHONE.m_phone]
- push eax
- lea eax, [edx + PHONE.m_name]
- push eax
- push offset g_szPrintItemFormat
- call crt_printf
- add esp,12
-
- ; 记录索引
- mov edx,g_nI
- mov g_nFindIndex,edx
- ; 记录地址
- mov edx,g_nTmp
- mov g_nFindPoint,edx
-
- ret
- not_find:
- ; 没找到则继续找
- inc g_nI ; i++
- jmp find_loop
- find_empty:
- ; 提示没有找到这条信息
- push offset g_szErrNotFind
- call crt_printf
- add esp,4
-
- mov g_nFindIndex,-1 ; 没找到 索引为-1
- mov g_nFindPoint,0 ; 没找到 地址为0
- ret
-
- PhoneFind endp
-
- ; 增加用户
- PhoneAdd proc
- ;判断容量是否满了
- mov eax,g_nCount
- mov ebx,g_max
- cmp eax,ebx
- jb phone_insert
- ; 如果容量满了输出提示
- push offset g_szErrMax
- call crt_printf
- add esp,4
- ret
- phone_insert:
- ; 计算地址
- mov ecx,g_nCount ; 当前容量
- imul eax,ecx,sizeof(PHONE) ; i*单个元素大小 = 偏移地址给edi
- lea edi,[g_book + eax] ; 电话本首地址 + 偏移地址 = 第i个元素的地址
-
- ; 提示输入姓名
- push offset g_szNameIn
- call crt_printf
- add esp,4
- ; 用户输入姓名
- lea eax,[edi + PHONE.m_name]
- push eax
- push offset g_szScanNameFormat
- call crt_scanf
- add esp,8
-
- ; 提示输入电话
- push offset g_szPhoneNumberIn
- call crt_printf
- add esp,4
- ; 用户输入电话
- lea eax,[edi + PHONE.m_phone]
- push eax
- push offset g_szScanNameFormat
- call crt_scanf
- add esp,8
- ; 当前容量+1
- inc g_nCount
- ; 插入成功
- push offset g_szTipsAdd
- call crt_printf
- add esp,4
- ret
-
- PhoneAdd endp
-
- ; 删除用户
- PhoneDel proc
- ; 寻找用户
- call PhoneFind
- cmp g_nFindIndex, -1
- je find_empty; 没有此用户
- ; 找到了用户后,第i个后面依次往前移动
-
- ; 循环次数 = 总容量 - 找到的索引
- ; 若找到的索引i=3 ,总容量max = 5, 5-3=2次,索引从0开始,即 3覆盖2, 4覆盖3
- mov ecx, g_max ;总容量
- mov eax, g_nFindIndex ;找到的数据,索引从0开始
- sub ecx, eax ;循环次数
-
- copy_loop:
- ; copy到当前容量后还没到Max需要提前结束循环
- ; 即 g_nFindIndex >= g_nCount 退出
- mov eax,g_nFindIndex
- mov ebx,g_nCount
- cmp eax, ebx
- jnb copy_over ; 提前结束
-
- mov eax, g_nFindIndex ;找到的数据,索引从0开始
- ; 计算i元素地址 = 电话本首地址 + 找到的索引 * 一个元素大小
- imul esi, eax, sizeof(PHONE)
- lea edi, [g_book + esi] ; i元素地址
- ;lea esi, [edi + sizeof(PHONE)] ; i下一个元素地址
- mov g_nTmp, edi
-
- ; PHONE类型刚好为16字节 也就是4次movsd就能实现拷贝了
- ; 保存外层 ecx
- push ecx
- ; 循环4次
- mov ecx,4
- copy_item:
- mov edi,g_nTmp
- mov esi,edi
- imul eax, ecx, 4
- lea edi,[edi + eax - 4]
- lea esi,[eax + esi + sizeof(PHONE) -4]
- movsd dword ptr[edi], dword ptr[esi]
- loop copy_item
- ; 内层循环完毕,还原ecx
- pop ecx
- ; 复制一次,寻找索引+1
- inc g_nFindIndex
- loop copy_loop ; 循环ecx次
- copy_over:
- ; 当前容量 - 1
- dec g_nCount
- ; 删除成功
- push offset g_szTipsDel
- call crt_printf
- add esp,4
- find_empty:
- ret
-
- PhoneDel endp
-
- ; 修改用户
- PhoneUpdate proc
- ; 寻找用户
- call PhoneFind
- cmp g_nFindIndex, -1
- je find_empty; 没有此用户
-
- ; 找到了 这个用户 进行数据更新
- ; 提示输入姓名
- push offset g_szNewNameIn
- call crt_printf
- add esp,4
- ; 用户输入新的姓名
- mov edx,g_nFindPoint
- lea eax,[edx + PHONE.m_name]
- push eax
- push offset g_szScanNameFormat
- call crt_scanf
- add esp,8
- ; 提示输入电话
- push offset g_szNewPhoneNumberIn
- call crt_printf
- add esp,4
- ; 用户输入新的电话
- mov edx,g_nFindPoint
- lea eax,[edx + PHONE.m_phone]
- push eax
- push offset g_szScanNameFormat
- call crt_scanf
- add esp,8
-
- ; 输出提示 修改成功
- push offset g_szTipsUpdate
- call crt_printf
- add esp,4
-
- find_empty:
- ret
-
- PhoneUpdate endp
-
- ; 打印所有用户
- PhoneShowAll proc
- mov g_nI,0
- print_loop:
- mov eax,g_nI
- cmp eax,g_nCount
- ; i<g_nCount 则打印
- jb print
- push offset g_szTipsNoMore
- call crt_printf
- add esp,4
- ret
- print:
- ; 计算地址
- imul eax,g_nI,sizeof(PHONE) ; i*单个元素大小 = 偏移地址给edi
- lea edi,[g_book + eax] ; 电话本首地址 + 偏移地址 = 第i个元素的地址
-
- ; 打印信息
- lea eax, [edi + PHONE.m_phone]
- push eax
- lea eax, [edi + PHONE.m_name]
- push eax
- push offset g_szPrintItemFormat
- call crt_printf
- add esp,12
- inc g_nI
- jmp print_loop
-
-
- PhoneShowAll endp
-
-
- main:
- ; 打印菜单获取用户指令
- call SelectMenu
- cmp g_nCmd, 1
- jne menu_add; 输入的是1(查询)继续执行,否则跳到下一个判断
- call PhoneFind
- jmp menu_end
- menu_add:
- cmp g_nCmd, 2
- jne menu_del ; 输入的是2(增加)继续执行,否则跳到下一个判断
- call PhoneAdd
- jmp menu_end
- menu_del:
- cmp g_nCmd, 3
- jne menu_update ; 输入的是3(删除)继续执行,否则跳到下一个判断
- call PhoneDel
- jmp menu_end
- menu_update:
- cmp g_nCmd, 4
- jne menu_showall ; 输入的是4(修改)继续执行,否则跳到下一个判断
- call PhoneUpdate
- jmp menu_end
- menu_showall:
- cmp g_nCmd, 5
- jne menu_unknow ; 输入的是5(查看所有)继续执行,否则跳到下一个判断
- call PhoneShowAll
- jmp menu_end
- menu_unknow: ; 输入的未知指令
- push offset g_szErrUnknowCmd
- call crt_printf
- add esp,4
- menu_end: ; 执行完毕返回菜单
- push offset g_szPause
- call crt_system
- add esp,4
- jmp main
- quit: ; 退出
- ret
-
- end main
-
- end
复制代码
|
|