创建/写入x86 Linux文件
我一直在努力自学一些32位x86(NASM)。我试图让用户输入文件名,打开/创建文件,然后获取用户的消息并将该消息写入文件。我已经在GDB中检查了它,所有的系统调用都正确返回。程序运行后,文件似乎创建不正确,没有写入任何内容。我见过其他一些类似的问题,但我的代码似乎与他们的代码几乎相同,所以我似乎不知道到底发生了什么 这是我的noob代码:创建/写入x86 Linux文件,linux,assembly,x86,Linux,Assembly,X86,我一直在努力自学一些32位x86(NASM)。我试图让用户输入文件名,打开/创建文件,然后获取用户的消息并将该消息写入文件。我已经在GDB中检查了它,所有的系统调用都正确返回。程序运行后,文件似乎创建不正确,没有写入任何内容。我见过其他一些类似的问题,但我的代码似乎与他们的代码几乎相同,所以我似乎不知道到底发生了什么 这是我的noob代码: global _start section .data fmsg: db "Enter Filename: ", 0 .len: equ $ -
global _start
section .data
fmsg: db "Enter Filename: ", 0
.len: equ $ - fmsg
umsg: db "Enter message: ", 0
.len: equ $ - umsg
buff: times 50 db 0 ;array for user string
.blen: equ $ - buff
fname: times 50 db 0 ;array for filename
.flen: equ $ - fname
;modes
O_RDONLY: db 0 ;read-only
O_WRONLY: db 1 ;wirte-only
O_RDWR: db 2 ;read and write
;flags
O_CREAT: dw 100o ;create file if file doesnt exists
O_TRUNC: dw 1000o ;truncate file
O_APPEND: dw 2000o ;append to file
section .bss
fd: resd 1 ;file descriptor
bret: resd 1 ;read buffer return value
fret: resd 1 ;read filename return value
tmp: resd 1 ;temp 4 byte variable
section .text
_start:
fprompt: ;Print prompt
mov eax, 0x4 ;syscall 4 - write()
mov ebx, 0x1 ;file desc 1 - stdout
mov ecx, fmsg ;print message
mov edx, fmsg.len ;length of message
int 80h ;syscall interupt
filein:
mov eax, 0x3 ;syscall 3 - read()
mov ebx, 0x0 ;file desc 0 - stdin
mov ecx, fname ;dst buffer
mov edx, fname.flen ;length of buffer
int 80h ;syscall interupt
mov [fret], eax ;save return value to file return variable
cmp eax, edx ;read max bytes or more?
jb fileopen ;jmp is bytes read < max
mov bl, [ecx+eax-1] ;grab last byte @ last index before '\0'
cmp bl, 10 ;does it = '\n' ?
je clean1
inc DWORD [fret] ;len++
clean1: ;loop to clear excess input, if any
mov eax, 0x3 ;syscall 3 - read()
mov ebx, 0x0 ;file desc 0 - stdin
mov ecx, tmp ;temp buffer
mov edx, 0x1 ;read only 1 byte
int 80h ;;syscall interupt
test eax, eax ;EOF?
jz fileopen ;Yes, jump to pback
mov al, [tmp] ;put character into lower 8 bits of EAX
cmp al, 10 ;is it = to lf ?
jne clean1 ;no, jump to begining of loop
fileopen:
mov eax, 0x05
mov ebx, fname ;filename
or ecx, O_CREAT ;if it doesn't exist create the file
or ecx, O_TRUNC ;truncate
mov edx, O_WRONLY ;write only
int 80h ;syscall interupt
mov [fd], eax ;save file descripor
prompt2:
mov eax, 0x4 ;syscall 4 - write()
mov ebx, 0x1 ;file desc 1 - stdout
mov ecx, umsg ;print message
mov edx, umsg.len ;length of message
int 80h
userin:
mov eax, 0x3 ;syscall 3 - read()
mov ebx, 0x0 ;file desc 0 - stdin
mov ecx, buff ;dst buffer
mov edx, buff.blen ;length of buffer
int 80h ;syscall interupt
mov [bret], eax ;save return value to buff return variable
cmp eax, edx ;read max bytes or more?
jb writetofile ;jmp is bytes read < max
mov bl, [ecx+eax-1] ;grab last byte @ last index before '\0'
cmp bl, 10 ;does it = '\n' ?
je clean2
inc DWORD [bret] ;len++
clean2: ;loop to clear excess input, if any
mov eax, 0x3 ;syscall 3 - read()
mov ebx, 0x0 ;file desc 0 - stdin
mov ecx, tmp ;temp buffer
mov edx, 0x1 ;read only 1 byte
int 80h ;syscall
test eax, eax ;EOF?
jz writetofile ;Yes, jump to pback
mov al, [tmp] ;put character into lower 8 bits of EAX
cmp al, 10 ;is it = to lf ?
jne clean2 ;no, jump to begining of loop
writetofile:
mov eax, 0x4 ;syscall 4 - write()
mov ebx, [fd] ;file desc 1 - stdout
mov ecx, buff ;print message
mov edx, [bret] ;length of message
int 80h ;syscall interupt
closefile:
mov eax, 0x6 ;syscall 6 - close()
mov ebx, [fd] ;file desc
int 80h ;syscall interupt
exit: ;return 0
mov eax, 1 ;syscall 1 - exit()
mov ebx, 0 ;return val
int 80h ;syscall interupt
global\u启动
第二节数据
fmsg:db“输入文件名:”,0
.len:eq$-fmsg
umsg:db“输入消息:”,0
.len:eq$-umsg
增益:乘以50分贝0;用户字符串的数组
.blen:eq$-buff
fname:乘以50分贝0;文件名数组
.flen:eq$-fname
;模式
orduonly:db 0;只读
O_WRONLY:db 1;仅限威特
O_RDWR:db 2;读写
;旗帜
O_CREAT:dw100o;如果文件不存在,则创建文件
O_TRUNC:dw 1000o;截断文件
O_追加:dw 2000o;附加到文件
第2节bss
fd:resd1;文件描述符
bret:resd1;读取缓冲区返回值
fret:resd1;读取文件名返回值
tmp:resd1;临时4字节变量
第节.案文
_开始:
提示:;打印提示
mov-eax,0x4;syscall 4-write()
mov-ebx,0x1;文件描述1-标准输出
mov ecx,fmsg;打印消息
mov-edx,fmsg.len;信息长度
int 80h;系统调用中断
文件输入:
mov-eax,0x3;syscall 3-read()
mov-ebx,0x0;文件描述0-stdin
mov-ecx,fname;dst缓冲区
mov-edx,fname.flen;缓冲区长度
int 80h;系统调用中断
mov[fret],eax;将返回值保存到文件返回变量
cmp-eax,edx;读取最大字节数还是更多?
jb文件打开;jmp是读取的字节数<最大值
mov bl,[ecx+eax-1];获取“\0”之前最后一个索引的最后一个字节
cmp bl,10;它是否='\n'?
日本脑炎1
德沃德公司;莱恩++
清洁1:;循环以清除多余的输入(如果有)
mov-eax,0x3;syscall 3-read()
mov-ebx,0x0;文件描述0-stdin
mov-ecx,tmp;临时缓冲区
mov-edx,0x1;只读1字节
int 80h;;系统调用中断
测试eax,eax;EOF?
jz文件开放;是的,跳到pback
mov-al[tmp];将字符放入EAX的低8位
cmp-al,10;这是你的吗?
jne-clean1;不,跳到循环的开始
文件打开:
mov-eax,0x05
mov-ebx,fname;文件名
或ecx,O_CREAT;如果不存在,请创建该文件
或ecx,O_TRUNC;截断
仅限mov edx,O_wr;只写
int 80h;系统调用中断
mov[fd],eax;保存文件描述符
提示2:
mov-eax,0x4;syscall 4-write()
mov-ebx,0x1;文件描述1-标准输出
mov ecx,umsg;打印消息
mov edx,umsg.len;信息长度
int 80h
用户输入:
mov-eax,0x3;syscall 3-read()
mov-ebx,0x0;文件描述0-stdin
mov-ecx,buff;dst缓冲区
mov-edx,buff.blen;缓冲区长度
int 80h;系统调用中断
mov[bret],eax;将返回值保存到buff返回变量
cmp-eax,edx;读取最大字节数还是更多?
jb写文件;jmp是读取的字节数<最大值
mov bl,[ecx+eax-1];获取“\0”之前最后一个索引的最后一个字节
cmp bl,10;它是否='\n'?
je清洁2
德沃德公司[bret];莱恩++
清洁2:;循环以清除多余的输入(如果有)
mov-eax,0x3;syscall 3-read()
mov-ebx,0x0;文件描述0-stdin
mov-ecx,tmp;临时缓冲区
mov-edx,0x1;只读1字节
int 80h;系统调用
测试eax,eax;EOF?
jz写文件;是的,跳到pback
mov-al[tmp];将字符放入EAX的低8位
cmp-al,10;这是你的吗?
jne-clean2;不,跳到循环的开始
写入文件:
mov-eax,0x4;syscall 4-write()
mov-ebx[fd];文件描述1-标准输出
mov-ecx,buff;打印消息
mov-edx[bret];信息长度
int 80h;系统调用中断
关闭文件:
mov-eax,0x6;syscall 6-close()
mov-ebx[fd];文件描述
int 80h;系统调用中断
出口:;返回0
mov-eax,1;syscall 1-exit()
mov-ebx,0;返回值
int 80h;系统调用中断
下面是一个运行后得到的示例:
文件“test.txt?”显示出来,并且显示为一个可执行文件,即使我只为该文件设置了读/写。即使我试着打开它,也什么都没有。有什么想法吗?另外,正如我提到的,我是新来的,正在自学,所以如果你对课程其他方面的改进有什么好的建议,请让我知道!:) 以下三行代码中有多个错误(或一个大错误):
or ecx, O_CREAT ;if it doesn't exist create the file
or ecx, O_TRUNC ;truncate
mov edx, O_WRONLY ;write only
问题是:
寄存器ecx
和edx
在这些行之后有什么值
您使用ecx
寄存器执行了两个或
操作,但显然此时它没有初始化
这意味着您可以确保设置了表示O_create
和O_TRUNC
(无论这些值是什么意思-见下文)的位,但您不知道其他位具有哪些值
O_WRONLY
位应在ecx
中设置,而不是在edx
中设置<代码>edx应包含所需的文件模式
不幸的是,有两种不同类型的汇编器-我不知道NASM属于哪种类型:
- 一种类型的汇编程序会将第一条指令解释为:
或ecx,[O_CREAT]
- 另一种类型将其解释为:
或ecx,地址为(O_CREAT)
O_RDONLY equ 0
O_WRONLY equ 1
O_RDWR equ 2
O_CREAT equ 100o ;create file if file doesnt exists
O_TRUNC equ 1000o ;truncate file
O_APPEND equ 2000o ;append to file
mov ecx, O_CREAT | O_TRUNC | O_WRONLY
mov edx, 0777o ; mode is the permission bits if open() creates the file
or ecx, O_CREAT ;if it doesn't exist create the file
or ecx, O_TRUNC ;truncate
movzx ecx, word [O_CREAT]
or cx, [O_TRUNC]
or cx, [O_WRONLY]