AT&T汇编语言学习:利用c库、文件读写
2016-03-21 01:00
821 查看
AT&T汇编、调用C库函数、读/写文件
d0321:更新读文件代码(图片)以后会更新代码版。
d0329:汇编文本读取、简单动画。
================================================
本文是利用AT&T风格调用C库,来读取文件内容。(如果安装的是64位的linux,需要安装32位的C库。并在利用gcc编译的时候加入-m32指令。)
64位利用32位库的编译指令如下:(-ggdb是加入gdb调试信息)
利用C库函数fscanf读文件
GDB调试代码
查看寄存器中的值
查看内存中的值
n表示要显示的内存单元的个数。
f表示显示方式, 可取如下值:
x 按十六进制格式显示变量。 d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。 o 按八进制格式显示变量。
c 按字符格式显示变量。f 按浮点数格式显示变量。
u表示一个地址单元的长度,可取下值
b表示单字节,h表示双字节,w表示四字节,g表示八字节。
汇编语言完成简单文本动画
在实现了基本的文件读取功能后,利用汇编语言制作了简单的动画(用空格实现)
该程序的基本流程如下:
运行截图:(其中1文件见下)
为动画效果,不好截图,可以将源码拷贝运行一次。
文件1
文件2
d0321:更新读文件代码(图片)以后会更新代码版。
d0329:汇编文本读取、简单动画。
================================================
本文是利用AT&T风格调用C库,来读取文件内容。(如果安装的是64位的linux,需要安装32位的C库。并在利用gcc编译的时候加入-m32指令。)
64位利用32位库的编译指令如下:(-ggdb是加入gdb调试信息)
gcc -m32 -ggdb readfile.s -o readfile
利用C库函数fscanf读文件
GDB调试代码
查看寄存器中的值
info reg
查看内存中的值
x/nfu <addr>
n表示要显示的内存单元的个数。
f表示显示方式, 可取如下值:
x 按十六进制格式显示变量。 d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。 o 按八进制格式显示变量。
c 按字符格式显示变量。f 按浮点数格式显示变量。
u表示一个地址单元的长度,可取下值
b表示单字节,h表示双字节,w表示四字节,g表示八字节。
汇编语言完成简单文本动画
在实现了基本的文件读取功能后,利用汇编语言制作了简单的动画(用空格实现)
该程序的基本流程如下:
.code32 .section .rodata #参数定义 mode: .string "r" sreturn: .string "Read file success" freturn: .string "Read file failed" space: .string " " printstring: .string "%s" colorRed: .string "\033[31m" colorYellow: .string "\033[33m" colorGreen: .string "\033[36m" nomalEnd: .string "\033[0m" colorType: .string "%s%s%s" clear: .string "clear" tmp: .string "@" #代码部分 .text #animation .globl animation .type animation, @function animation: pushl %ebp movl %esp, %ebp subl $200, %esp #设置该函数的栈区为ebp-200 xorl %eax, %eax #clear %eax movl $0,-108(%ebp) #设置刷新10次 file_open: pushl $mode #将文件读取模式压入栈 pushl 8(%ebp) call fopen addl $8, %esp #清除上面压栈的mode和path check_open: cmpl $0, %eax #eax中接着的是返回值 je read_fail #如果无法读取就跳转 read_sus: movl %eax, -104(%ebp) #将文件指针保存在-104 pushl $sreturn #输出成功读取文件提示 call puts addl $4, %esp #清除上面压栈的sreturn pushl $clear #将clear指令压栈 call system #调用system系统函数,用来清屏 addl $4,%esp #清除上面压栈的一个参数 read_one_line: pushl -104(%ebp) #这里是把ebp-104里面存的的值压进去(fp) pushl $200 #将fgets的第二个参数压栈 leal -100(%ebp), %eax #将从文件中读取的数据保存到ebp-100 pushl %eax #这里是把ebp-100的这个值(地址压进去) call fgets addl $12, %esp #清除压栈参数 check_EOF: pushl -104(%ebp) #这里是把ebp-104里面存的的值压进去(fp) call feof addl $4, %esp #清除上面压栈的一个参数 cmpl $0,%eax #判断返回值 jne close_file movl -108(%ebp),%ebx #将刷新参数读到ebx print_space: #pushl $tmp #call printf #addl $4,%esp cmpl $0,%ebx je print_text #如果已经打印完了就开始输出数据 pushl $space #打印空格 pushl $printstring call printf addl $8,%esp #清理压栈 subl $1,%ebx #循环参数减一 jmp print_space print_text: leal -100(%ebp), %eax #将刚才读出来的数据压栈,准备输出 pushl $nomalEnd pushl %eax pushl $colorYellow pushl $colorType call printf addl $4, %esp #清除上面压栈的一个参数 jmp read_one_line close_file: pushl -104(%ebp) #把文件指针压栈 call fclose #关闭文件 addl $4, %esp #清除上面压栈的一个参数 movl $0, -104(%ebp) #清空文件指针 movl -108(%ebp),%ebx #当缓冲空格已经结束 cmp $30,%ebx je end_main addl $1,%ebx #刷新剩余次数加一 movl %ebx,-108(%ebp) #保存起来 pushl $80000 #sleep参数 call usleep pushl $clear #清屏 call system addl $8,%esp jmp file_open read_fail: pushl $freturn #输出读取失败文件提示 call puts addl $4, %esp #清除上面压栈的一个参数 end_main: leave ret #main .section .rodata welcomemsg: .string "================================================================\n Welcome!\n Please Input the filename you wantta play!\n================================================================\n" askagain: .string "again?(y/n)" stringType: .string "%s" yes: .string "y" no: .string "n" inttype: .string "%d" .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $50,%esp #主函数栈区 pushl $welcomemsg call printf addl $4,%esp leal -4(%ebp),%eax #输入文件路径 pushl %eax pushl $stringType call scanf addl $8,%esp start: leal -4(%ebp),%eax pushl %eax call animation #播放开启动画 addl $4,%esp ask: pushl $askagain #again? call printf addl $4,%esp leal -14(%ebp), %eax #y/n pushl %eax pushl $stringType call scanf addl $8, %esp subl $16, %esp #is y? leal -14(%ebp), %eax pushl %eax pushl $yes call strcmp addl $24, %esp cmpl $0,%eax je start subl $16, %esp #is n? leal -14(%ebp), %eax pushl %eax pushl $no call strcmp addl $24, %esp cmpl $0,%eax je endmain jmp ask endmain: leave ret
运行截图:(其中1文件见下)
为动画效果,不好截图,可以将源码拷贝运行一次。
文件1
########### # # # # ### # # ### # # # # # # # # # # # # #############################
文件2
==== ==== ==== |||| ==== ==== ==== |||| ==== ==== |||| ==== ==== ==== |||| ============ ==== |||| ============ ==== |||| ==== ==== ==== ==== ==== ==== |||| ==== ==== ==== ||||
相关文章推荐
- Chromium网页渲染机制简要介绍和学习计划
- 关闭 Visual Studio 2013 的 Browser Link 功能
- 主板基础知识
- C语言实现有序二叉树(1)
- 展望C++17
- PostgreSQL之通过数据库模型生成数据库表
- Python体验(10)-图形界面之计算器
- Linux服务器架设篇之(二)–源码安装Web服务器Nginx
- 16 API-集合(List的子类(ArrayList_Vector_LinkedList,集合嵌套遍历),JDK5新特性(泛型,增强for循环,静态导入,可变参数)
- MFC->消息对话框、文件对话框、字体对话框、颜色对话框
- bat面试题总结
- 怎么从包名上区别“源代码包”和“二进制包”
- Linux笔记(63)——nginx负载均衡实现
- Java Lambda表达式入门
- Size classe ---Xcode 6中的自动布局
- 算法浅谈——数据结构
- 网易互娱2017实习生招聘在线笔试第一场-2源代码编译
- 作业——在线学习Android课程之第三周
- const的作用
- 【cocos2dx 3.10】简述 cocos studio 的使用