为什么执行`cmpq`指令都会产生`sign sigttin,toped'?

发布于 2025-02-09 21:10:14 字数 5439 浏览 1 评论 0原文

我正在阅读从地面上进行编程并使用程序中的文件阅读第5章。,第63页中的代码。

我试图让此32位代码转换为64位代码。

以下是我的代码。

# system call numbers
.equ SYS_OPEN, 2
.equ SYS_WRITE, 1
.equ SYS_READ, 0
.equ SYS_CLOSE, 3
.equ SYS_EXIT, 60

.equ O_RDONLY, 0
.equ O_CREAT_WRONLY_TRUNC, 03101

# standard file descriptors
.equ STDIN, 0
.equ STDOUT, 1
.equ STDERR, 2

# system call interrupt
.equ LINUX_SYSCALL, 0x80
.equ END_OF_FILE, 0

.equ NUMBER_ARGUMENTS, 2

.section .bss
.equ BUFFER_SIZE, 500
.lcomm BUFFER_DATA, BUFFER_SIZE

.section .text

# STACK POSITIONS
.equ ST_SIZE_RESERVE, 16
.equ ST_FD_IN, -8
.equ ST_FD_OUT, -16
# main function arguments
.equ ST_ARGC, 0     # Number of arguments
.equ ST_ARGV_0, 8   # Name of program
.equ ST_ARGV_1, 16  # Input file name
.equ ST_ARGV_2, 24  # Output file name

.globl _start
_start:

    ### INITIALIZE PROGRAM ###
    # save the stack pointer
    movq %rsp, %rbp
    
    # Allocate space for our file descriptors on the stack
    subq $ST_SIZE_RESERVE, %rsp

open_files:
open_fd_in:
    ### OPEN INPUT FILE ###
    # open syscall
    movq $SYS_OPEN, %rax
    # input filename into %rbx
    movq ST_ARGV_1(%rbp), %rbx

    # read-only flag
    movq $O_RDONLY, %rcx
    # this doesn't really matter for reading
    movq $0666, %rdx
    # call Liunx
    int $LINUX_SYSCALL

store_fd_in:
    # save the given file descriptor
    movq %rax, ST_FD_IN(%rbp)

open_fd_out:
    ### OPEN OUTPUT FILE ###
    # open the file
    movq $SYS_OPEN, %rax
    # output filename into %rbx
    movq ST_ARGV_2(%rbp), %rbx
    # flags for writing to the file
    movq $O_CREAT_WRONLY_TRUNC, %rcx
    # mode for new file (if it's created)
    movq $0666, %rdx
    # call Linux
    int $LINUX_SYSCALL

store_fd_out:
    # store the file descriptor here
    movq %rax, ST_FD_OUT(%rbp)

    ### BEGIN MAIN LOOP ###
read_loop_begin:
    ### READ IN A BLOCK FROM THE INPUT FILE ###
    movq $SYS_READ, %rax
    # get the input descriptor
    movq ST_FD_IN(%rbp), %rbx
    # the location to read into
    movq $BUFFER_DATA, %rcx
    # the size of the buffer
    movq $BUFFER_SIZE, %rdx
    # Size of buffer read is returned in %rax
    int $LINUX_SYSCALL
    
    ### EXIT IF WE'RE REACHED THE END ###
    # check for end of file marker
    cmpq $END_OF_FILE, %rax
    # if found or on error, go to the end
    jle end_loop

continue_read_loop:
    ### CONVERT THE BLOCK TO UPPER CASE ###
    pushq $BUFFER_DATA  # loction of buffer
    pushq %rax      # size of the buffer
    callq convert_to_upper  
    popq %rax       # get the size back
    addq $8, %rsp       # restore %rsp

    ### WRITE THE BLOCK OUT TO THE OUTPUT FILE ###
    # size of the buffer
    movq %rax, %rdx
    movq $SYS_WRITE, %rax
    # file to use
    movq ST_FD_OUT(%rbp), %rbx
    # location of the buffer
    movq $BUFFER_DATA, %rcx
    int $LINUX_SYSCALL
    
    ### CONTINUE THE LOOP ###
    jmp read_loop_begin

end_loop:
    ### CLOSE THE FILES ###
    movq $SYS_CLOSE, %rax
    movq ST_FD_OUT(%rbp), %rbx
    int $LINUX_SYSCALL
    
    movq $SYS_CLOSE, %rax
    movq ST_FD_IN(%rbp), %rbx
    int $LINUX_SYSCALL

### EXIT ###
    movq $SYS_EXIT, %rax
    movq $0, %rbx
    int $LINUX_SYSCALL
    

### CONSTANTS ###
# The lower boundary of our search
.equ LOWERCASE_A, 'a'
# The lower boundary of our search
.equ LOWERCASE_Z, 'z'
# Conversion between upper and lower case
.equ UPPER_CONVERSION, 'A' - 'a'


### STACK STUFF ###
.equ ST_BUFFER_LEN, 24  # length of buffer
.equ ST_BUFFER, 32  # actual buffer

convert_to_upper:
    pushq %rbp
    movq %rsp, %rbp

### SET UP VARIABLES ###
    movq ST_BUFFER(%rbp), %rax
    movq ST_BUFFER_LEN(%rbp), %rbx
    movq $0, %rdi

    # if a buffer with zero length was given to us, just leave
    cmpq $0, %rbx
    je end_convert_loop
    
convert_loop:
    # get the current byte
    movb (%rax, %rdi, 1), %cl
    
    # go to the next byte unless it is between  
    # 'a' and 'z'
    cmpb $LOWERCASE_A, %cl
    jl next_byte
    cmpb $LOWERCASE_Z, %cl
    jg next_byte

    # otherwise convert the byte to uppercase
    addb $UPPER_CONVERSION, %cl
    # and store it back
    movb %cl, (%rax, %rdi, 1)

next_byte:
    incq %rdi   # next byte
    cmpq %rdi, %rbx # continue unless we've reached the end
    jne convert_loop

end_convert_loop:
    # no return value, just leave
    movq %rbp, %rsp
    popq %rbp
    retq

我运行此代码,它将出现分割故障(Core丢弃),然后我尝试使用GDB发现错误。

以下是我有问题!

  1. 一开始,它没有创建文件,然后我发现系统呼叫号码已更改,它不适用我的Ubuntu AMD 64位。最后,我检查了此 file ,然后修改了我的我的代码。现在,我想知道有关AMD64的最新系统电话号码。 http://www.x86-64.org无法访问!
  2. 为什么执行int $ linux_syscall出现[从子进程中分离后的叉子...],请使用b 61b 78设置断点!
  3. 最后一个问题是该帖子标题,在代码read_loop_begin部分中,cmpq $ end_of_file,%rax出现signal sigttin,停止。设置之前删除断点,然后使用b 99重置断点,然后将r用于重新运行程序!然后,程序执行序列与我的期望不符,为什么在执行cmp后,为什么不直接进入contine_read_loop e节,而不是直接进入convert_to_to_to_upper,然后出现无法找到当前功能的界限

最后,如果有任何逻辑错误等,请指出它们!我深表感谢。 :-)

I'm reading Programming from the Ground Up, and read the Chapter 5's Using Files in a Program., code in Page 63.

I tried to let this 32bit code convert to 64bit code.

Below is my code.

# system call numbers
.equ SYS_OPEN, 2
.equ SYS_WRITE, 1
.equ SYS_READ, 0
.equ SYS_CLOSE, 3
.equ SYS_EXIT, 60

.equ O_RDONLY, 0
.equ O_CREAT_WRONLY_TRUNC, 03101

# standard file descriptors
.equ STDIN, 0
.equ STDOUT, 1
.equ STDERR, 2

# system call interrupt
.equ LINUX_SYSCALL, 0x80
.equ END_OF_FILE, 0

.equ NUMBER_ARGUMENTS, 2

.section .bss
.equ BUFFER_SIZE, 500
.lcomm BUFFER_DATA, BUFFER_SIZE

.section .text

# STACK POSITIONS
.equ ST_SIZE_RESERVE, 16
.equ ST_FD_IN, -8
.equ ST_FD_OUT, -16
# main function arguments
.equ ST_ARGC, 0     # Number of arguments
.equ ST_ARGV_0, 8   # Name of program
.equ ST_ARGV_1, 16  # Input file name
.equ ST_ARGV_2, 24  # Output file name

.globl _start
_start:

    ### INITIALIZE PROGRAM ###
    # save the stack pointer
    movq %rsp, %rbp
    
    # Allocate space for our file descriptors on the stack
    subq $ST_SIZE_RESERVE, %rsp

open_files:
open_fd_in:
    ### OPEN INPUT FILE ###
    # open syscall
    movq $SYS_OPEN, %rax
    # input filename into %rbx
    movq ST_ARGV_1(%rbp), %rbx

    # read-only flag
    movq $O_RDONLY, %rcx
    # this doesn't really matter for reading
    movq $0666, %rdx
    # call Liunx
    int $LINUX_SYSCALL

store_fd_in:
    # save the given file descriptor
    movq %rax, ST_FD_IN(%rbp)

open_fd_out:
    ### OPEN OUTPUT FILE ###
    # open the file
    movq $SYS_OPEN, %rax
    # output filename into %rbx
    movq ST_ARGV_2(%rbp), %rbx
    # flags for writing to the file
    movq $O_CREAT_WRONLY_TRUNC, %rcx
    # mode for new file (if it's created)
    movq $0666, %rdx
    # call Linux
    int $LINUX_SYSCALL

store_fd_out:
    # store the file descriptor here
    movq %rax, ST_FD_OUT(%rbp)

    ### BEGIN MAIN LOOP ###
read_loop_begin:
    ### READ IN A BLOCK FROM THE INPUT FILE ###
    movq $SYS_READ, %rax
    # get the input descriptor
    movq ST_FD_IN(%rbp), %rbx
    # the location to read into
    movq $BUFFER_DATA, %rcx
    # the size of the buffer
    movq $BUFFER_SIZE, %rdx
    # Size of buffer read is returned in %rax
    int $LINUX_SYSCALL
    
    ### EXIT IF WE'RE REACHED THE END ###
    # check for end of file marker
    cmpq $END_OF_FILE, %rax
    # if found or on error, go to the end
    jle end_loop

continue_read_loop:
    ### CONVERT THE BLOCK TO UPPER CASE ###
    pushq $BUFFER_DATA  # loction of buffer
    pushq %rax      # size of the buffer
    callq convert_to_upper  
    popq %rax       # get the size back
    addq $8, %rsp       # restore %rsp

    ### WRITE THE BLOCK OUT TO THE OUTPUT FILE ###
    # size of the buffer
    movq %rax, %rdx
    movq $SYS_WRITE, %rax
    # file to use
    movq ST_FD_OUT(%rbp), %rbx
    # location of the buffer
    movq $BUFFER_DATA, %rcx
    int $LINUX_SYSCALL
    
    ### CONTINUE THE LOOP ###
    jmp read_loop_begin

end_loop:
    ### CLOSE THE FILES ###
    movq $SYS_CLOSE, %rax
    movq ST_FD_OUT(%rbp), %rbx
    int $LINUX_SYSCALL
    
    movq $SYS_CLOSE, %rax
    movq ST_FD_IN(%rbp), %rbx
    int $LINUX_SYSCALL

### EXIT ###
    movq $SYS_EXIT, %rax
    movq $0, %rbx
    int $LINUX_SYSCALL
    

### CONSTANTS ###
# The lower boundary of our search
.equ LOWERCASE_A, 'a'
# The lower boundary of our search
.equ LOWERCASE_Z, 'z'
# Conversion between upper and lower case
.equ UPPER_CONVERSION, 'A' - 'a'


### STACK STUFF ###
.equ ST_BUFFER_LEN, 24  # length of buffer
.equ ST_BUFFER, 32  # actual buffer

convert_to_upper:
    pushq %rbp
    movq %rsp, %rbp

### SET UP VARIABLES ###
    movq ST_BUFFER(%rbp), %rax
    movq ST_BUFFER_LEN(%rbp), %rbx
    movq $0, %rdi

    # if a buffer with zero length was given to us, just leave
    cmpq $0, %rbx
    je end_convert_loop
    
convert_loop:
    # get the current byte
    movb (%rax, %rdi, 1), %cl
    
    # go to the next byte unless it is between  
    # 'a' and 'z'
    cmpb $LOWERCASE_A, %cl
    jl next_byte
    cmpb $LOWERCASE_Z, %cl
    jg next_byte

    # otherwise convert the byte to uppercase
    addb $UPPER_CONVERSION, %cl
    # and store it back
    movb %cl, (%rax, %rdi, 1)

next_byte:
    incq %rdi   # next byte
    cmpq %rdi, %rbx # continue unless we've reached the end
    jne convert_loop

end_convert_loop:
    # no return value, just leave
    movq %rbp, %rsp
    popq %rbp
    retq

I run this code, it will appear Segmentation fault (core dumped), and then I tried to using gdb to found errors.

Below are I have problems!

  1. In the beginning, it was not creating files, and then I found system call numbers is changed, it was not applicable my ubuntu amd 64bit. finally, I examined this file, then modified my code. Now, I wanna know latest system call numbers about amd64. http://www.x86-64.org can't visit!!
  2. Why is executing int $LINUX_SYSCALL appear [Detaching after fork from child process ...], please use b 61 and b 78 set breakpoint!
  3. The last question is this post title, in code read_loop_begin section, cmpq $END_OF_FILE, %rax appear signal SIGTTIN, Stopped. Delete breakpoint before set, and use b 99 reset breakpoint, and then use r to rerun program! And then the program execution sequence is not in line with my expectations, why is not straight into continue_read_loop section after cmp executed, rather than straight into convert_to_upper section, and then appear Cannot find bounds of current function

Finally, if there are any logical errors, etc, please point them out! I'm deeply grateful. :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文