程序集 - 带有子程序的段错误
Assembly - Segfault with subprogram
我正在尝试调试为什么我的子程序出现段错误。
它发生在子程序末尾的 ret 行上——就像在句子末尾到达 0x00 字节一样。
主要内容:
.data
string: .string "aaaaaaaaaaa"
endofstring: .space 8
msg: .string "%c occurs %d times \n"
.text
.global main
main:
mov $string,%rsi #rsi = string storage
mov [=10=]x61, %ah #storage of a
mov [=10=]x65, %al #storage of e
mov [=10=]x69, %bh #storage of i
mov [=10=]x6F, %bl #storage of o
mov [=10=]x75, %ch #storage of u
#Case A
mov %ah,%cl #1 byte register for cmp later on.
mov [=10=], %rax #initialize count to 0
call FREQ #Generate %rax value for
mov %rax, %rdx #count for printf (2nd argument)
mov $msg, %rdi #format for printf(1st argument)
mov %r8, %rsi #ch for printf (3rd argument)
xor %rax, %rax #reset %rax for printf output
call printf #print the frequency value of the ch in string
#Case E
mov %al,%cl
mov [=10=], %rax #initialize count to 0
call FREQ
mov %rax, %rdx #count for printf (2nd argument)
mov $msg, %rdi #format for printf(1st argument)
mov %r8, %rsi #ch for printf (3rd argument)
xor %rax, %rax #reset %rax for printf output
call printf #print the frequency value of the ch in string
#Case O
mov %bh,%cl
mov [=10=], %rax #initialize count to 0
call FREQ
mov %rax, %rdx #count for printf (2nd argument)
mov $msg, %rdi #format for printf(1st argument)
mov %r8, %rsi #ch for printf (3rd argument)
xor %rax, %rax #reset %rax for printf output
call printf #print the frequency value of the ch in string
#Case I
mov %bl,%cl
mov [=10=], %rax #initialize count to 0
call FREQ
mov %rax, %rdx #count for printf (2nd argument)
mov $msg, %rdi #format for printf(1st argument)
mov %r8, %rsi #ch for printf (3rd argument)
xor %rax, %rax #reset %rax for printf output
call printf #print the frequency value of the ch in string
#Case U
mov %ch,%cl
mov [=10=], %rax #initialize count to 0
call FREQ
mov %rax, %rdx #count for printf (2nd argument)
mov $msg, %rdi #format for printf(1st argument)
mov %r8, %rsi #ch for printf (3rd argument)
xor %rax, %rax #reset %rax for printf output
call printf #print the frequency value of the ch in string
jmp done
done:
ret
子程序:
.text
.globl FREQ
FREQ:
#subprogram body
Start:
cmpb [=11=],8(%rsi) #check for end of the string
je donefreq
loopfreq:
cmp %cl, 8(%rsi) #compare first string char with vowel
je incrementstring #if equal - jump to increment_string
add , %rsi #if not - increment string
jmp Start #jump to loop to check for end of string status/next char
incrementstring:
add , %rsi #increment to next string character
add , %rax #add 1 to frequency of character
jmp Start
donefreq:
ret
不确定为什么会这样。 - 我希望调试能提供更多信息:(
有人知道为什么会这样吗?我完全按照被调用者函数的注释大纲进行操作,所以我不知道问题出在被调用者
您不应使用 %rsp
作为指向字符串的指针。您正在破坏堆栈中的 return 地址,因此您的 ret
指令试图跳转到某个虚假地址。使用 %rsi
或其他通用寄存器。堆栈指针不是一个你可以随意使用的寄存器。
我正在尝试调试为什么我的子程序出现段错误。
它发生在子程序末尾的 ret 行上——就像在句子末尾到达 0x00 字节一样。
主要内容:
.data
string: .string "aaaaaaaaaaa"
endofstring: .space 8
msg: .string "%c occurs %d times \n"
.text
.global main
main:
mov $string,%rsi #rsi = string storage
mov [=10=]x61, %ah #storage of a
mov [=10=]x65, %al #storage of e
mov [=10=]x69, %bh #storage of i
mov [=10=]x6F, %bl #storage of o
mov [=10=]x75, %ch #storage of u
#Case A
mov %ah,%cl #1 byte register for cmp later on.
mov [=10=], %rax #initialize count to 0
call FREQ #Generate %rax value for
mov %rax, %rdx #count for printf (2nd argument)
mov $msg, %rdi #format for printf(1st argument)
mov %r8, %rsi #ch for printf (3rd argument)
xor %rax, %rax #reset %rax for printf output
call printf #print the frequency value of the ch in string
#Case E
mov %al,%cl
mov [=10=], %rax #initialize count to 0
call FREQ
mov %rax, %rdx #count for printf (2nd argument)
mov $msg, %rdi #format for printf(1st argument)
mov %r8, %rsi #ch for printf (3rd argument)
xor %rax, %rax #reset %rax for printf output
call printf #print the frequency value of the ch in string
#Case O
mov %bh,%cl
mov [=10=], %rax #initialize count to 0
call FREQ
mov %rax, %rdx #count for printf (2nd argument)
mov $msg, %rdi #format for printf(1st argument)
mov %r8, %rsi #ch for printf (3rd argument)
xor %rax, %rax #reset %rax for printf output
call printf #print the frequency value of the ch in string
#Case I
mov %bl,%cl
mov [=10=], %rax #initialize count to 0
call FREQ
mov %rax, %rdx #count for printf (2nd argument)
mov $msg, %rdi #format for printf(1st argument)
mov %r8, %rsi #ch for printf (3rd argument)
xor %rax, %rax #reset %rax for printf output
call printf #print the frequency value of the ch in string
#Case U
mov %ch,%cl
mov [=10=], %rax #initialize count to 0
call FREQ
mov %rax, %rdx #count for printf (2nd argument)
mov $msg, %rdi #format for printf(1st argument)
mov %r8, %rsi #ch for printf (3rd argument)
xor %rax, %rax #reset %rax for printf output
call printf #print the frequency value of the ch in string
jmp done
done:
ret
子程序:
.text
.globl FREQ
FREQ:
#subprogram body
Start:
cmpb [=11=],8(%rsi) #check for end of the string
je donefreq
loopfreq:
cmp %cl, 8(%rsi) #compare first string char with vowel
je incrementstring #if equal - jump to increment_string
add , %rsi #if not - increment string
jmp Start #jump to loop to check for end of string status/next char
incrementstring:
add , %rsi #increment to next string character
add , %rax #add 1 to frequency of character
jmp Start
donefreq:
ret
不确定为什么会这样。 - 我希望调试能提供更多信息:(
有人知道为什么会这样吗?我完全按照被调用者函数的注释大纲进行操作,所以我不知道问题出在被调用者
您不应使用 %rsp
作为指向字符串的指针。您正在破坏堆栈中的 return 地址,因此您的 ret
指令试图跳转到某个虚假地址。使用 %rsi
或其他通用寄存器。堆栈指针不是一个你可以随意使用的寄存器。