我正在尝试创建一个以字符串作为输入(由0,1和2组成)的程序,并检查字符串[i + 1]元素是否大于字符串[i]。如果它更大,程序返回1,如果它不大,它返回-1。我一直遇到分段错误,我不知道它可能在哪里。
程序的其余部分有更多的代码,但我已经确认其余的工作,并且只在调用“sort”时引发Seg Fault。
我的代码:
sort:
enter 0,0
pusha
mov edx, dword [ebp+8] ;address of string
mov edi, dword [ebp+12] ;first index
mov esi, dword [ebp+16] ;second index
LOOPYDOOPY:
cmp byte [edx+edi], 0 ;check if the character at first index is 0
je RETMINUS
cmp byte [edx+esi], 0 ;if character at second is 0
je RETPLUS
mov al, byte [edx+esi] ;if first element is greater than second element
cmp byte [edx+edi], al
jl RETMINUS
cmp byte [edx+edi], al ;firstt < second
jg RETPLUS
inc edi
inc esi
jmp LOOPYDOOPY
RETPLUS:
popa
mov eax, 1 ;return 1
jmp END
RETMINUS:
popa
mov eax, -1 ;return -1
END:
leave
ret
答案 0 :(得分:0)
不,你被证实排序引发了段错误,而不是代码的其余部分正好相反。
实际上排序本身没问题,我从你的问题中1:1复制了它,只添加了调用排序并显示结果的测试(你可以验证我没有修改你的#34中的单个字符;排序:&#34;),它有效:
(要验证转到http://www.tutorialspoint.com/compile_assembly_online.php并粘贴此来源+运行它。)
section .text
global _start
_start:
lea ebx,[testString]
xor ecx,ecx ; ecx (i) = 0
.loopI:
cmp [ebx+ecx+2],byte 0
je .allCompared ; not "all", should have been ecx+1 above.
lea edx,[ecx+1] ; edx (j) = i+1
.loopJ:
; call sort
push edx ; j
push ecx ; i
push ebx ; string adr (! OP missing the diff betwen adr and content)
call sort
add esp,12
; display result
mov esi,ecx ; copy i/j to esi/edi
mov edi,edx
test eax,eax
js .firstWasSmaller
xchg esi,edi ; swap esi/edi, esi is "smaller" now
.firstWasSmaller:
pushad
call displaySingleString
mov edx,lenLess
mov ecx,msgLess
call displayStr
xchg esi,edi ; swap esi/edi, esi is "smaller" now
call displaySingleString
mov edx,lenNL
mov ecx,msgNL
call displayStr
popad
; continue in loop
inc edx
cmp [ebx+edx],byte 0
jnz .loopJ
inc ecx
jmp .loopI
.allCompared:
mov eax, 1 ;system call number (sys_exit)
int 0x80 ;call kernel
displaySingleString: ; display partial string from testString+esi
mov edx,testLen
sub edx,esi
lea ecx,[testString+esi]
displayStr:
mov ebx, 1 ;file descriptor (stdout)
mov eax, 4 ;system call number (sys_write)
int 0x80 ;call kernel
ret
; original poster code follows, as is (intact):
sort:
enter 0,0
pusha
mov edx, dword [ebp+8] ;address of string
mov edi, dword [ebp+12] ;first index
mov esi, dword [ebp+16] ;second index
LOOPYDOOPY:
cmp byte [edx+edi], 0 ;check if the character at first index is 0
je RETMINUS
cmp byte [edx+esi], 0 ;if character at second is 0
je RETPLUS
mov al, byte [edx+esi] ;if first element is greater than second element
cmp byte [edx+edi], al
jl RETMINUS
cmp byte [edx+edi], al ;firstt < second
jg RETPLUS
inc edi
inc esi
jmp LOOPYDOOPY
RETPLUS:
popa
mov eax, 1 ;return 1
jmp END
RETMINUS:
popa
mov eax, -1 ;return -1
END:
leave
ret
; read only test data + formatting strings
section .rodata
testString: db '00100102', 0
testLen equ $ - testString - 1
msgLess db ' < '
lenLess equ $ - msgLess
msgNL db 0x0a
lenNL equ $ - msgNL
输出我得到:
sh-4.3$ nasm -f elf *.asm; ld -m elf_i386 -s -o demo *.o
sh-4.3$ demo
00100102 < 0100102
00100102 < 100102
00100102 < 00102
00100102 < 0102
00100102 < 102
00100102 < 02
00100102 < 2
0100102 < 100102
00102 < 0100102
0100102 < 0102
0100102 < 102
0100102 < 02
0100102 < 2
00102 < 100102
0102 < 100102
100102 < 102
02 < 100102
100102 < 2
00102 < 0102
00102 < 102
00102 < 02
00102 < 2
0102 < 102
0102 < 02
0102 < 2
02 < 102
102 < 2
sh-4.3$