gpt4 book ai didi

linux - 读写文件汇编

转载 作者:太空宇宙 更新时间:2023-11-04 09:24:35 24 4
gpt4 key购买 nike

我有一个inputfile.txt,它看起来如下:3 4 2 0 8 1 5 3
我试着在一个outputfile.txt中写入输入文件的每个字符递增1。
所以在outputfile.txt中我应该可以看到4 5 3 1 9 2 6 4
我试过写这段代码,但有几个疑问。

.section .data
buff_size: .long 18

.section .bss
.lcomm buff, 18

.section .text # declaring our .text segment
.globl _start # telling where program execution should start

_start:

popl %eax # Get the number of arguments
popl %ebx # Get the program name
popl %ebx # Get the first actual argument - file to read

# open the file
movl $5, %eax # open
movl $0, %ecx # read-only mode
int $0x80

# read the file

movl $0, %esi
movl %eax, %ebx # file_descriptor

analyzecharacter: #here I want to read a single character
movl $3, %eax
movl $buff, %edi
leal (%esi,%edi,1), %ecx
movl $1, %edx
int $0x80
add $1, %esi #this point is not clear to me, what I'd like to do is to increment the index of the buffer in order to be positioned on the next cell of buffer array, I've added 1 but I think is not correct
cmp $8, %esi # if I've read all 8 characters then I'll exit
je exit

openoutputfile:
popl %ebx # Get the second actual argument - file to write
movl $5, %eax # open
movl $2, %ecx # read-only mode
int $0x80

writeinoutputfile:
#increment by 1 and write the character to STDOUT
movl %eax, %ebx # file_descriptor
movl $4, %eax
leal (%esi,%edi,1), %ecx
add $1, %ecx #increment by 1
movl $1, %edx
int $0x80
jmp analyzecharacter

exit:
movl $1, %eax
movl $0, %ebx
int $0x80

我有两个问题/疑问:
我的第一个疑问是这个指令: add $1, %esi。这是在 buffer数组中移动的正确方法吗?
第二个疑问是:当我分析每个字符时,我应该总是调用 openoutputfilelabel?我想这样我就重新打开了文件,以前的内容被覆盖了。
实际上,如果我运行程序,我只看到一个字符 \00(一个垃圾字符,由此指令中的%esi值引起,我猜是: leal (%esi,%edi,1), %ecx)。
我希望我的问题是明确的,我是相当新的集会,我花了几个小时在这方面。
FYI: 
I'm using GAS Compiler and the syntax is AT&T.
Moreover I'm on Ubuntu 64 bit and Intel CPU.

最佳答案

所以,我该怎么做代码。。。
考虑到这一点,我已经习惯了英特尔的语法,以至于我无法在没有错误的情况下从我的头脑中编写AT&T源代码(而且我太懒了,无法真正做真正的事情并调试它),所以我会尽量避免完整地编写指令,只描述过程,让您填写指令。
所以让我们决定你想一个一个地做,我的源代码的版本1:

start:
; verify the command line has enough parameters, if not jump to exitToOs
; open both input and output files at the start of the code
processingLoop:
; read single char
; if no char was read (EOF?), jmp finishProcessing
; process it
; write it
jmp processingLoop
finishProcessing:
; close both input and output files
exitToOs:
; exit back to OS

现在“运行”它在您的头脑中,验证所有主要分支点的意义,并将正确处理所有主要角落的情况。
确保您理解代码的工作方式、循环位置以及循环中断的位置和原因。
确保没有无限循环或资源泄漏
在浏览完我的清单之后,这个设计有一个微妙的问题,它没有严格地检查文件系统错误,比如不能打开任何一个文件,或者编写字符(但是你的源代码也不在乎)。否则我认为它应该能很好地工作。
因此,让我们在版本2中对其进行扩展,使其更接近实际的ASM指令(带星号的指令是由我编写的,因此,对于混乱的语法,这些指令的最终版本由您决定):
start:
; verify the command line has enough parameters, if not jump to exitToOs
popl %eax # Get the number of arguments
* cmpl $3,eax ; "./binary fileinput fileoutput" will have $3 here?? Debug!
* jnz exitToOs

; open both input and output files at the start of the code
movl $5, %eax # open
popl %ebx # Get the program name

; open input file first
popl %ebx # Get the first actual argument - file to read
movl $0, %ecx # read-only mode
int $0x80
cmpl $-1, %eax ; valid file handle?
jz exitToOs
* movl %eax, ($varInputHandle) ; store input file handle to memory

; open output file, make it writable, create if not exists
movl $5, %eax # open
popl %ebx # Get the second actual argument - file to write
* ; next two lines should use octal numbers, I hope the syntax is correct
* movl $0101, %ecx # create flag + write only access (if google is telling me truth)
* movl $0666, %edx ; permissions for out file as rw-rw-rw-
int $0x80
cmpl $-1, %eax ; valid file handle?
jz exitToOs
movl %eax, ($varOutputHandle) ; store output file handle to memory

processingLoop:

; read single char to varBuffer
movl $3, %eax
movl ($varInputHandle), %ebx
movl $varBuffer, %ecx
movl $1, %edx
int $0x80

; if no char was read (EOF?), jmp finishProcessing
cmpl $0, %eax
jz finishProcessing ; looks like total success, finish cleanly

;TODO process it
* incb ($varBuffer) ; you wanted this IIRC?

; write it
movl $4, %eax
movl ($varOutputHandle), %ebx # file_descriptor
movl $varBuffer, %ecx ; BTW, still set from char read, so just for readability
movl $1, %edx ; this one is still set from char read too
int $0x80

; done, go for the next char
jmp processingLoop

finishProcessing:
movl $0, ($varExitCode) ; everything went OK, set exit code to 0

exitToOs:
; close both input and output files, if any of them is opened
movl ($varOutputHandle), %ebx # file_descriptor
call closeFile
movl ($varInputHandle), %ebx
call closeFile

; exit back to OS
movl $1, %eax
movl ($varExitCode), %ebx
int $0x80

closeFile:
cmpl $-1, %ebx
ret z ; file not opened, just ret
movl $6, %eax ; sys_close
int $0x80
; returns 0 when OK, or -1 in case of error, but no handling here
ret

.data
varExitCode: dd 1 ; no idea about AT&T syntax, "dd" is "define dword" in NASM
; default value for exit code is "1" (some error)
varInputHandle: dd -1 ; default = invalid handle
varOutputHandle: dd -1 ; default = invalid handle
varBuffer: db ? ; (single byte buffer)

哇,我真的写得很完整吗?(当然它需要语法检查+清除星号,还有“;”用于注释等。)
但我的意思是,第1版的评论已经非常详细,每一条都只需要少量的ASM指令,所以并不难(尽管现在我看到我在53分钟前提交了第一个答案,所以这对我来说大约需要1小时的工作(包括谷歌搜索和其他一些差事)。
我完全不明白为什么有些人会想使用AT&t语法,这是如此荒谬的冗长。我很容易理解GCC为什么要使用它,对于编译器来说这是非常好的。
但是,也许您应该检查NASM,它是面向“人”的(尽可能少地编写语法糖,并专注于指令)。NASM的主要问题(或我认为的优势)是英特尔语法,例如, MOV eax,ebx将number ebx放入 eax中,这是英特尔的错误,采用了其他微处理器制造商的 LD语法,忽略了LD=load的含义,并将其改为MOV=MOV e以避免公然复制指令集。
再说一遍,我完全不知道为什么 ADD $1,%eax是AT&T的正确方法(而不是 eax,1顺序),我甚至不想知道,但这对我来说没有任何意义(相反的 MOV至少有一些意义,因为 LD英特尔 MOV语法的起源)。
OTHH可以与 cmp $number,%reg有关,因为我开始在C++中使用“YODA”格式避免在 if中意外地改变变量值(比较: if (0 = variable) vs if (variable = 0),都有冒号 =而不是通缉< cc>。即使关闭警告,“yoda”也不会编译。
但是。。。哦。。这是我这周最后一次回答AT&T的问题,真让我恼火。(我知道这是个人偏好,但所有这些额外的 ==$都让我很恼火,就像相反的顺序一样)。
拜托,我花了很多时间写这个。试着花认真的时间研究它,试着去理解它。如果感到困惑,请在评论中提问,但如果你完全没有抓住要点,没有从中学到任何有用的东西,那将是对我们时间的浪费。:)继续。
最后一点:努力寻找一些调试器,找到一些适合你的东西(可能有些像DOS时代Borland的老“TD”这样的可视调试器对新手来说是非常好的),但是对于你来说,快速改进是绝对必要的,能够在代码上一步一步地指令,看看寄存器和内存内容是如何改变值的。实际上,如果您能够调试自己的代码,您很快就会意识到您正在从 %中错误的文件句柄读取第二个字符。。。(至少我希望如此)。

关于linux - 读写文件汇编,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37940707/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com