汇编语言学c,AT&T汇编语言学习:利用c库、文件读写

AT&T汇编、调用C库函数、读/写文件

d0321:更新读文件代码(图片)以后会更新代码版。

d0329:汇编文本读取、简单动画。

================================================

本文是利用AT&T风格调用C库,来读取文件内容。(如果安装的是64位的linux,需要安装32位的C库。并在利用gcc编译的时候加入-m32指令。)

64位利用32位库的编译指令如下:(-ggdb是加入gdb调试信息)

gcc -m32 -ggdb readfile.s -o readfile

利用C库函数fscanf读文件

28e10f0504b5a0705dcc80f214e10dbf.png

cf28bf7839bbece7c4019d1d2738057c.png

1023eb40609eb402427b6c6c75ac99f8.png

f9f15ca5cd0e3cb63170176cc80fd206.png

b4fa0b76152e1f330ae764b0c08347ab.png

18d600232e6d59d46dd6e40775cae3d0.png

d228441c0faf2c194783fe95cd597231.png

GDB调试代码

查看寄存器中的值

info reg

73b50df3513ebc418dfdc5e8e0312087.png

查看内存中的值

x/nfu

n表示要显示的内存单元的个数。

f表示显示方式, 可取如下值:

x 按十六进制格式显示变量。 d 按十进制格式显示变量。

u 按十进制格式显示无符号整型。 o 按八进制格式显示变量。

c 按字符格式显示变量。f 按浮点数格式显示变量。

u表示一个地址单元的长度,可取下值

b表示单字节,h表示双字节,w表示四字节,g表示八字节。

b7fca072c99317fb13de2ee8700c6659.png

汇编语言完成简单文本动画

在实现了基本的文件读取功能后,利用汇编语言制作了简单的动画(用空格实现)

该程序的基本流程如下:

d78f119ce5e75a1f5e749957812f2898.png

.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文件见下)

07f1ca96ccc174440d9305b2ace23e73.png

为动画效果,不好截图,可以将源码拷贝运行一次。

3d0aa5aa263c08c6cba90d06cef8a6f6.png

文件1

###########

# #

# #

### # # ###

# # # # # #

# #

# #

# #

#############################

文件2

==== ==== ==== ||||

==== ==== ==== ||||

==== ==== ||||

==== ==== ==== ||||

============ ==== ||||

============ ==== ||||

==== ==== ====

==== ==== ==== ||||

==== ==== ==== ||||

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值