汇编电话本

用汇编写出的电话本项目

直接放代码吧

.386
.model flat,stdcall
option casemap:none

include msvcrt.inc
includelib msvcrt.lib
include user32.inc
includelib user32.lib
include windows.inc
include kernel32.inc
includelib kernel32.lib

.data
; 暂停
str_system_pause db “pause”, 0dh, 0ah, 0
; 用于保存菜单的选项
choose dd 0
; 用于存储跳转表的数据
; 跳转表,保存 case 块的地址
jmp_table dd case1, case2, case3, case4,case5,case6
;定义结构体
CONTACTSSTRUCT struct
szName BYTE 25 dup(0) ;name
szPhNmuber BYTE 12 dup(0) ;phone number
CONTACTSSTRUCT ends

PCONTACTSSTRUCT TYPEDEF PTR CONTACTSSTRUCT ;取别名,指针类型

g_stContacts CONTACTSSTRUCT 100 dup(<‘0’>) ;定义结构体数组
g_nCount DWORD 0 ;元素个数
g_nMaxCount DWORD 100 ;MAX元素个数
g_strTemContacts CONTACTSSTRUCT <‘0’,‘0’> ;接收输入信息

;定义格式控制符,用于输入输出时用到的格式控制符
g_szScanfFormat BYTE ‘%s %s’,0h
g_szScanfName BYTE ‘%s’,0h
g_szScanfByte BYTE ‘%c’,0h
.const ;常量数据
sz_put_name db “请输入要添加的用户名,密码:”,0h
sz_find_name db “请输入要查找的用户名:”,0h
sz_change_name db “请输入要修改的name”,0h
sz_remove_name db “请输入要删除的name”,0h
sz_put_number db"please enter a number",0h
g_szOK db"删除OK",0h
; 清空屏幕
str_printf_size db “超出容量”, 0dh, 0ah, 0
; 格式控制符
str_format_int db “%d”, 0
; 菜单项
str_show_menu db “1. 添加数据”, 0dh, 0ah,
“2. 显示数据”, 0dh, 0ah,
“3. 查找数据”, 0dh, 0ah,
“4. 删除数据”, 0dh, 0ah,
“5. 修改数据”, 0dh, 0ah,
“6. 退出程序”, 0dh, 0ah,
"请输入选项: ", 0
; 0dh 0ah == \r\n 0 字符串结尾
;tr_show_menu db “1.添加数据”,
.code
; 清空屏幕
str_system_cls db “cls”, 0
GET_CHAR PROC
push eax
push offset g_szScanfByte;%c
call crt_scanf
add esp,8h
ret

GET_CHAR endp
ADD_USER proc ;无参数

lea eax,sz_put_name
push eax	;提示输入名字
call crt_printf		;打印sz_put_name
add esp,4h ;平衡参数	;平衡

	xor eax,eax
	xor ecx,ecx	
;cmp ecx,[g_nMaxCount]	;判断是否超过最大容量

lea esi,[g_stContacts] 

mov ecx,g_nCount	;获取已存放信息个数

mov eax,sizeof(CONTACTSSTRUCT) 
imul eax,ecx
add esi,eax;数组大小,乘以 count


lea edx,[esi+CONTACTSSTRUCT.szName]
lea eax,[esi+CONTACTSSTRUCT.szPhNmuber]
push eax
push edx

;push eax
push offset g_szScanfFormat
call crt_scanf
add esp,12
inc g_nCount ;++

ret

ADD_USER endp
;---------------------------------
FindData proc
xor ecx,ecx
xor eax,eax
xor ebx,ebx
;1.输入数据
lea eax,sz_put_name
push eax ;提示输入名字
call crt_printf ;打印sz_put_name
add esp,4h ;平衡参数 ;平衡

lea edi,[g_strTemContacts.szName]
push edi
push offset g_szScanfName
call crt_scanf
add esp,8
;2.开始查询
mov ecx,0
CYCLE_MARK:
cmp ecx,g_nCount
jz Exit_cycle
;2.1根据ecx的值,找到下一个结构体的名字数组的地址
lea esi,[g_stContacts]			;源串
lea edi,[g_strTemContacts.szName]	;用于比较的字符串
mov eax,sizeof(CONTACTSSTRUCT)
imul eax,ecx
add esi,eax
;2.2比较字符串
mov eax,ecx	;保存了循环次数,当前循环了第几次了
mov ecx,6		;初始化字符串,因为是25个字节,但末尾是0,而用dword4字节,4*6  24
repe cmpsd dword ptr[esi],dword ptr[edi]
je CARRIEDOUT_MARK
mov ecx,eax
INC ECX		;自增
jmp CYCLE_MARK
CARRIEDOUT_MARK:
;输出信息
mov ecx,eax
lea esi,[g_stContacts]
mov ebx,sizeof(CONTACTSSTRUCT)
imul ebx,ecx
add esi,ebx
lea eax,[esi+CONTACTSSTRUCT.szPhNmuber]
push eax
push offset g_szScanfName
call crt_printf
add esp,8

Exit_cycle:
ret

FindData endp
;修改用户信息
CHANGE PROC

;1.输入信息
push offset sz_change_name
call crt_printf
add esp,4

lea edi,[g_strTemContacts.szName]
push edi
push offset g_szScanfName
call crt_scanf
add esp,8
;2.开始查询
mov ecx,0
CYCLE_MARK:
cmp ecx,g_nCount
jz Exit_cycle	;if 找不到就退出
;2.1根据ecx的值,找到下一个结构体的名字数组的地址
lea esi,[g_stContacts]
lea edi,[g_strTemContacts.szName]
mov eax,sizeof(CONTACTSSTRUCT)
imul eax,ecx
add esi,eax
;2.2比较字符串
mov eax,ecx
mov ecx,6
repe cmpsd dword ptr[esi],dword ptr[edi]
je CARRIEDOUT_MARK
mov ecx,eax
inc ecx
jmp CYCLE_MARK
CARRIEDOUT_MARK:
;修改信息
mov ecx,eax
lea esi,[g_stContacts]
mov ebx,sizeof(CONTACTSSTRUCT)
imul ebx,ecx
add esi,ebx
;1.输入信息
push offset sz_change_name
call crt_printf
add esp,4

;1.1修改信息
lea edx,[esi+CONTACTSSTRUCT.szName]
lea eax,[esi+CONTACTSSTRUCT.szPhNmuber]
push eax
push edx
push offset g_szScanfFormat
call crt_scanf
add esp,12

Exit_cycle:
ret

CHANGE endp

RemoveData proc
;1.输入信息
push offset sz_remove_name
call crt_printf
add esp,4

lea esi,[g_strTemContacts.szName]
push esi
push offset g_szScanfName
call crt_scanf
add esp,8
;2.循环遍历
mov ecx,0
CYCLE_MARK:
cmp ecx,g_nCount
jz Exit_cycle
push ecx	;先push进去
;2.1根据ecx的值,找到下一个结构体的名字数组的地址
lea esi,[g_stContacts]			;源串
lea edi,[g_strTemContacts.szName]	;用于比较的字符串
mov eax,sizeof(CONTACTSSTRUCT)
imul eax,ecx
add esi,eax
;2.2比较字符串
mov eax,ecx	;保存了循环次数,当前循环了第几次了
mov ecx,6		;初始化字符串,因为是25个字节,但末尾是0,而用dword4字节,4*6  24
repe cmpsd dword ptr[esi],dword ptr[edi]
je CARRIEDOUT_MARK
pop ecx
;mov ecx,eax
INC ECX		;自增
jmp CYCLE_MARK
CARRIEDOUT_MARK:
;删除
;将esi设置为当前要删除的结构体数组
pop ecx
;mov ecx,eax
lea edi,[g_stContacts]
mov ebx,sizeof(CONTACTSSTRUCT)
imul ebx,ecx
add edi,ebx		;edi保存的是,当前要删除的结构体数组的首地址
mov esi,edi
mov ebx,sizeof(CONTACTSSTRUCT)
add esi,ebx		;esi 指向要删除的结构体数组的下一个元素的首地址
add ecx,eax
mov eax,g_nCount
sub eax,ecx
mov ebx,sizeof(CONTACTSSTRUCT)
imul ebx,eax
mov ecx,ebx		;计算need mov的字节
rep movs BYTE PTR[edi],BYTE ptr [esi];开始移动(以一个字节开始移动)
;移动完成后删除最后一个结构体中的信息
mov ebx,sizeof(CONTACTSSTRUCT)
push ebx
push 0
push edi
call crt_memset
add esp,12

dec g_nCount

push offset g_szOK
call crt_printf
add esp,4
push 2000
call Sleep	;此函数不用自己平衡栈  需要包含头文件include kernel32.inc		cludelib kernel32.lib

Exit_cycle:
ret

RemoveData endp

ShowData proc
mov ecx,0
CYCLE_MARK:

cmp ecx,g_nCount

jz CARRIEDOUT_MARK
push ecx;一定要在cmp下,不然在cmp前,一终止,就无法pop了
;造成栈不平衡
;2.依次打印
lea esi,[g_stContacts]			;源串
mov eax,sizeof(CONTACTSSTRUCT)
imul eax,ecx
add esi,eax
;1.1输出
lea edx,[esi+CONTACTSSTRUCT.szName]
lea eax,[esi+CONTACTSSTRUCT.szPhNmuber]
push eax
push edx
push offset g_szScanfFormat
call crt_printf
add esp,12
pop ecx
inc ecx
jmp CYCLE_MARK
CARRIEDOUT_MARK:
ret

ShowData endp
; 函数:退出程序
exit_pragma proc
push 0
call crt_exit
ret
exit_pragma endp
main:
begin_while:

; 打印菜单项: print(arg)
push offset str_show_menu
call crt_printf
; crt 函数是 c 语言提供的的
; 所以需要平衡堆栈 _cdecl
add esp, 4

 ; 获取用户的输入 scanf("%d", &choose)
push offset choose
push offset str_format_int
call crt_scanf
; 有两个参数,需要平衡 2*4 字节
add esp, 8

; switch case 的实现
; 1. 获取到当前输入的数据对应的[下标]

mov ecx, [choose]
dec ecx
; 2. 判断下标是否在有效范围(case)之内
cmp ecx, 4
; 3. 如果传入的数据不在表中,那么跳转到 default
ja default
; 4. 否则查表进行跳转
jmp dword ptr [jmp_table+ecx*4]
case1:
; 添加数据
call ADD_USER
jmp endswitch
case2:
; 显示数据
call ShowData
jmp endswitch
case3:
; 查找数据
call FindData
jmp endswitch
case4:
;删除数据
call RemoveData
jmp endswitch
case5:
; 修改数据
call CHANGE
jmp endswitch
case6:
; 退出程序
call exit_pragma
jmp endswitch
default:
; 表示输入错误,直接进入下一次循环
jmp begin_while
push 500
call Sleep
endswitch:
; 添加一个暂停
push offset str_system_pause
call crt_system
add esp, 4
; 清空屏幕
push offset str_system_cls
call crt_system
add esp, 4
jmp begin_while
;call ADD_USER
;call FindData
; xor ecx,ecx
; xor eax,eax
; xor ebx,ebx
;
; push offset g_stContacts.szName
; call crt_printf ;打印
; add esp,4h
; push offset g_stContacts.szPhNmuber
; call crt_printf ;打印
; add esp,4h
;
; call ADD_USER
;
; xor ecx,ecx
; xor eax,eax
; xor ebx,ebx
;
; lea esi,[g_stContacts]
; ;mov ecx,g_nCount-1 代表是地址-1 mov ecx,g_nCountv相当于 取了 g_nCount的值放到ecx中
; mov ecx,g_nCount
; dec g_nCount ;获取已存放信息个数
;; sub ecx,1
;;mov ecx,2-1
; mov eax,sizeof(CONTACTSSTRUCT)
; imul eax,ecx
; add esi,eax;数组大小,乘以 count
;
; lea eax,[esi+CONTACTSSTRUCT.szName]
;
; lea edx,[esi+CONTACTSSTRUCT.szPhNmuber]
;
; push edx
;
; push eax
;
; ;push offset g_stContacts.szName
; call crt_printf ;打印
; add esp,4h
; pop edx
; push edx
; ;push offset g_stContacts.szName+25H
; call crt_printf ;打印 打印不出来的原因是因为,上一个call会改变edx中的值
; add esp,4h
ret
end main
end

亲测成功运行

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您可以通过以下步骤配置汇编语言环境: 1. 安装 Xcode 开发工具,可以在 App Store 中下载安装。 2. 打开终端,输入以下命令安装 Homebrew 包管理器: `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` 3. 使用 Homebrew 安装 NASM 汇编器: `brew install nasm` 4. 编写汇编代码,使用 NASM 编译器将代码编译成可执行文件: `nasm -f macho64 -o hello.o hello.asm` 5. 使用 ld 链接器将可执行文件链接成可执行程序: `ld -macosx_version_min 10.7. -lSystem -o hello hello.o` 6. 运行程序: `./hello` 希望这些步骤能够帮助您成功配置汇编语言环境。 ### 回答2: 要配置Mac笔记本的汇编语言环境,可以按照以下步骤进行: 第一步,安装Xcode。Xcode是苹果公司开发的一种集成开发环境(IDE),它包含了Mac OS和iOS开发所需的各种工具和库。前往App Store,搜索并下载Xcode,安装完成后打开应用程序。 第二步,安装命令行工具。在打开的Xcode应用程序中,点击菜单栏中的"Xcode",选择"Preferences"。在弹出的窗口中,选择"Locations"标签,在"Command Line Tools"下拉菜单中选择最新版本的命令行工具,并点击"Install"按钮进行安装。 第三步,安装汇编语言编译器。打开终端(Terminal)应用程序,在命令行中输入"brew install nasm",然后按下回车键。这将使用Homebrew包管理器自动下载和安装NASM(Netwide Assembler)编译器,它是一种常用的汇编语言编译器。 第四步,创建汇编源文件。在任意文本编辑器中创建一个新文件,并将其保存为".asm"扩展名的文件。例如,可以命名为"hello.asm"。 第五步,编写汇编源代码。在创建的汇编源文件中,使用汇编语言编写你想要的代码。例如,可以使用标准的x86汇编语言编写一个简单的"Hello, World!"程序。 第六步,编译和运行程序。在终端中,使用"nasm -f macho64 -o hello.o hello.asm"命令将汇编源文件编译为一个目标文件。然后,使用"ld -o hello -e _main hello.o"命令将目标文件链接为可执行文件。最后,使用"./hello"命令运行程序。 通过以上步骤,你就可以在Mac笔记本上成功配置汇编语言环境,并编写、编译和运行汇编语言程序了。请注意,汇编语言是一种底层的编程语言,对于初学者可能有一定的学习曲线,建议在学习之前阅读相关的教程和文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值