我在汇编中编写了此示例程序,以使用syscall和功能进行训练。第一个函数printString
正常工作,它打印给定的字符串。问题出在readString
函数中,它应该读取STRLEN
个字符,然后返回:
section .data
; Define standard constants.
LF equ 10 ; line feed
NULL equ 0 ; end of string
EXIT_SUCCESS equ 0 ; success code
STDIN equ 0 ; standard input
STDOUT equ 1 ; standard output
SYS_read equ 0 ; read
SYS_write equ 1 ; write
SYS_exit equ 60 ; terminate
; Define some strings.
STRLEN equ 10
pmpt db "Enter Text: ", NULL
newLine db LF, NULL
section .bss
chr resb 1
inLine resb STRLEN+2 ; total of 52
section .text
global _start
_start:
; Display prompt.
mov rdi, pmpt
call printString
mov rdi, inLine
mov rsi, STRLEN
mov rdx, chr
call readString
; Output the line to verify successful read
mov rdi, rax
call printString
; Example done.
exampleDone:
mov rax, SYS_exit
mov rdi, EXIT_SUCCESS
syscall
; ******************************************************
; Generic procedure to display a string to the screen.
; String must be NULL terminated.
; Algorithm:
; Count characters in string (excluding NULL)
; Use syscall to output characters
; Arguments:
; 1) address, string
; Returns:
; nothing
global printString
printString:
push rbx
; Count characters in string.
mov rbx, rdi
mov rdx, 0
strCountLoop:
cmp byte [rbx], NULL
je strCountDone
inc rdx
inc rbx
jmp strCountLoop
strCountDone:
cmp rdx, 0
je prtDone
; Call OS to output string.
mov rax, SYS_write ; system code for write()
mov rsi, rdi ; address of char's to write
mov rdi, STDOUT ; standard out
; RDX=count to write, set above
syscall ; system call
; String printed, return to calling routine.
prtDone:
pop rbx
ret
global readString
readString:
push rbx
push r12
push r11
mov rcx, rsi
; Read characters from user (one at a time)
mov rbx, rdi ; inLine addr
mov r11, rdx
mov r12, 0 ; char count
readCharacters:
mov rax, SYS_read; system code for read
mov rdi, STDIN; standard in
lea rsi, byte[r11] ; address of chr
mov rdx, 1 ; count (how many to read)
syscall ; syscall
mov al, byte [r11] ; get character just read
cmp al, 10 ; if linefeed, input done
je readDone
inc r12 ; count++
cmp r12, rcx ; if # chars > STRLEN
jae readCharacters ; stop placing in buffer
mov byte [rbx], al ; inLine[i] = chr
inc rbx ; update tmpStr addr
jmp readCharacters
readDone:
mov al, bl
pop r11
pop r12
pop rbx
ret
在最后第六行mov al, bl
中,我将结果返回到main函数。但是,当我传递到printString
时,它出现了分段错误。我使用gdb
在rbx
的{{1}}寄存器中进行了调试,但是实际上它不包含字符串,但是为什么呢?如果我在主字符串的x/s $rbx
中编写代码,则它可以正常工作。我认为当我传递参数以及在函数中推送和弹出寄存器时,我失去了一些东西。
编辑 这是寄存器的内容:
readString
它发生在第93行的分段错误中,这是对(gdb) info register
rax 0x1 1
rbx 0x402011 4202513
rcx 0x4010a0 4198560
rdx 0x1 1
rsi 0x402010 4202512
rdi 0x0 0
rbp 0x0 0x0
rsp 0x7fffffffe1b0 0x7fffffffe1b0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x206 518
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x4010a0 0x4010a0 <readCharacters+26>
eflags 0x206 [ PF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
的系统调用。
您能帮我吗? 预先感谢