Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建/写入x86 Linux文件_Linux_Assembly_X86 - Fatal编程技术网

创建/写入x86 Linux文件

创建/写入x86 Linux文件,linux,assembly,x86,Linux,Assembly,X86,我一直在努力自学一些32位x86(NASM)。我试图让用户输入文件名,打开/创建文件,然后获取用户的消息并将该消息写入文件。我已经在GDB中检查了它,所有的系统调用都正确返回。程序运行后,文件似乎创建不正确,没有写入任何内容。我见过其他一些类似的问题,但我的代码似乎与他们的代码几乎相同,所以我似乎不知道到底发生了什么 这是我的noob代码: global _start section .data fmsg: db "Enter Filename: ", 0 .len: equ $ -

我一直在努力自学一些32位x86(NASM)。我试图让用户输入文件名,打开/创建文件,然后获取用户的消息并将该消息写入文件。我已经在GDB中检查了它,所有的系统调用都正确返回。程序运行后,文件似乎创建不正确,没有写入任何内容。我见过其他一些类似的问题,但我的代码似乎与他们的代码几乎相同,所以我似乎不知道到底发生了什么

这是我的noob代码:

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]