您的位置:首页 > 其它

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调试信息)

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

====    ====    ====    ||||
====    ====    ====    ||||
====    ====            ||||
====    ====    ====    ||||
============    ====    ||||
============    ====    ||||
====    ====    ====
====    ====    ====    ||||
====    ====    ====    ||||
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: