【问题标题】:64bit NASM file handling problems64bit NASM 文件处理问题
【发布时间】:2013-11-29 03:46:16
【问题描述】:

我设法在我的 64 位 Linux 系统上编写了一个 NASM 程序,该程序从输入中删除非字母符号并将每个单词打印在单独的行中。问题是我得到 RCX = -1 我必须得到读取的字符号,结果我得到分段错误。我已经花了几个小时试图弄清楚如何修复这个错误。希望你们能帮助我。提前致谢。

这是我的代码:

section .data

file1   db "data", 0
file2   db "results", 0

text        times 255 db 0
textSize    equ $ - text
buff        times 255 db 0
buffSize    equ $ - buff    


section .text
global main
main:
    mov         rax, 2
    mov     rdi, file1
    mov     rsi, 0          ;read only
    mov     rdx, 0x7777
    syscall                 ;open file1
    mov     rbx, rax        ;save fd to rbx
    mov     rsi, text           ; a pointer to the current character 

    mov     rax, 0
    mov     rdi, rbx        ;fd of file1
    mov     rsi, text
    mov     rdx, textSize
    syscall                 ;read the text from file1 

    mov     rax, 3
    mov     rdi, rbx
    syscall                 ;close file1

    mov     rcx, rax        ; rcx  - character counter

    mov     rbx, buff       ;rbx will be our buffer

    cmp     rcx, 0
    je      exit            ; if nothing to read - exit

process_loop1:
    mov     dl, byte[rsi]

    cmp     byte[rsi], 0x41     ; "A"
    jl      inc1
    cmp     byte[rsi], 0x5a     ; "Z"
    jle     save
    cmp     byte[rsi], 0x61     ; "a"
    jl      inc1
    cmp     byte[rsi], 0x7a     ; "z"
    jle     save
    jmp     inc1                ;check text

inc1:
    inc     rsi
    dec     rcx
    jnz     process_loop1
    jmp     print

save:                   
    mov     byte [ebx], dl
    jmp     inc2            ;save letters


inc2:
    inc     rsi
    inc     rbx
    dec     rcx
    jnz     process_loop2
    jmp     print



process_loop2:
    mov     dl, byte[rsi]

    cmp     byte[rsi], 0x41     ; "A"
    jl      enter
    cmp     byte[rsi], 0x5a     ; "Z"
    jle     save
    cmp     byte[rsi], 0x61     ; "a"
    jl      enter
    cmp     byte[rsi], 0x7a     ; "z"
    jle     save
    jmp     enter



enter:
    mov     byte [ebx], 10      ;enter
    inc     rsi
    inc     rbx
    dec     rcx
    jnz     process_loop1
    jmp     print

print:                  
    mov         rax, 2
    mov     rdi, file2
    mov     rsi, 1      ;write only
    mov     rdx, 0x7777
    syscall                     ;open file2
    mov     rbx, rax    ;save fd to rbx


    mov     rax, 1
    mov     rdi, rbx
    mov     rsi, buff
    mov     rdx, buffSize
    syscall                 ;print result

    mov     rax, 3
    mov     rdi, rbx
    syscall                 ;close file2
    jmp     exit

exit:
    mov     rax, 60
    mov     rdi, 0
    syscall

【问题讨论】:

  • 为什么要使用“幻数”?如果您使用mov rax, sys_open 而不是mov rax, 2,它不会让您的代码自我记录吗
  • 你在哪一行得到分段错误?您是否尝试在调试器中运行您的程序? (汇编程序员不应该需要手持......)
  • 我用 gdb 测试了程序,发现在 sys_read 调用之后 rax 保持值 -1 而不是读取的符号数。我怎样才能得到符号的数量?
  • 这可能暗示sys_readsys_open(或两者)失败。
  • 当我进一步测试编程时,我设法弄清楚 sys_read 和 sys_open 工作,当我检查数据文件中的字母是否不为空时,程序确实读取了文件并打印了结果计算读取的符号数量,它只是不会终止,直到它溢出,整个缓冲区大小为 255 位,填充 '00\00\00\00\00\00\00\00\00\00\00\00\00 \00\00\...'

标签: linux assembly linux-kernel x86-64 nasm


【解决方案1】:

您在sys_read 和您尝试检查接收的字节数之间有一个sys_close。因此,您正在检查关闭的返回值,而不是读取。另请注意,rcx 已被系统调用破坏,因此您不能只向上移动 mov rcx, rax 行。

另外,在一些地方你使用 [ebx] 而不是 [rbx]。

此外,您可能希望将O_CREAT 用于结果文件,并且只写入您已处理的字节数,而不是buffSize

【讨论】:

    【解决方案2】:
    section .data
        filename db 'AVG.asm'
    
    
    section .bss
        buffer resb 2000
        fd_in resb 1
    
    section .text
        global _start
    _start:
            mov rax,2
            mov rdi,filename
            mov rsi,0
            mov rdx,0777
            syscall
    
            mov [fd_in],rax
    
            mov rax,0
            mov rdi,[fd_in]     
            mov rsi,buffer
            mov rdx,2000
            syscall
    
    
            mov rax,1
            mov rdi,1
            mov rsi,buffer
            mov rdx,2000
            syscall
    
    
    
            mov rax,3
            mov rdi,[fd_in]
            syscall
    
            mov rax,60
            mov rdi,0
            syscall
    

    【讨论】:

    • 你应该解释更多关于你在那里做什么。提出问题的人需要从您的回答中学到一些东西。
    猜你喜欢
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    • 2023-01-09
    • 2016-10-31
    • 2013-12-06
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多