我正在尝试在NASM中编写一个代码来反转一个字符串,但我不断遇到seg错误。我找到了一些问类似的问题,但回复并没有帮助我。
下面是代码:
%include "asm_io.inc"
segment .data
prompt1 db `Enter String: `,0
prompt2 db "Reverse: ",0
segment .bss
stringlabel resd 100
segment .text
global reverse
extern printf
extern scanf
reverse:
call readstring
call strlen
mov eax, 5
mov ebx, stringlabel ;save first address of the string
;eax contains the string length
add eax, ebx ;last address of the string
sub eax, 1 ;account for null character
whileReverse:
mov ecx, [eax] ;save value of last marker into a temp register
mov edx, [ebx] ;save value of first marker into a temp register
mov [ebx], ecx ;save value in ecx to the memory location pointed by ecx
mov [eax], edx ;save value in edx to the memory location pointed by eax
inc ebx ;increment first marker, i.e,move closer to the centre
dec eax ;decrement last marker
cmp eax, ebx ;if first marker is larger then the second marker, then swapping is done
ja whileReverse
whileReverseEnd:
popa
leave
ret
readstring:
enter 0,0 ;setup routine
pusha ;push all registers
mov eax, prompt1 ;move user input (String) into the register
call print_string ;print prompt on terminal
;READ A BYTE FROM STDIN
;this sub-block of code is to read the user input
;I found it on the NASM wikibooks site
;I have an idea of what may be going on
;But I am not sure why all these registers
;are being used
mov eax, 3 ;read
mov ebx, 0 ;read from standard input
mov ecx, stringlabel ;address to pass
mov edx, 100 ;input length
;must save the input string
;in eax (requirement)
int 0x80 ;call the kernal
call print_string ;print user input on terminal
popa
ret
strlen:
enter 0,0
pusha
mov eax, prompt1 ;save the address of the first memory 'block' of stringlabel in eax
mov ebx, eax ;move both markers to the first memory 'block' address
whileLen:
mov cl, [eax] ;move value from eax to lower ecx
cmp cl, 0 ;look for null value in the current address
je whileLenEnd ;exit loop if null value is found in the current address
inc eax ;else, increment eax to move on to the next memory location or 'block'
jmp whileLen ;jump back to while loop and repeat
whileLenEnd:
sb eax, ebx ;subtract the final positions of the markers to calculate the string length must save the string length in eax {requirement)
pop ebx
pop ecx
leave
ret
答案 0 :(得分:1)
将5分配给EAX会破坏调用strlen的目的。只需删除它。
call strlen
mov eax, 5
以下行的评论是错误的。将EAX放在字符串的最后一个字符上需要减量。
sub eax, 1 ;account for null character
您需要将字符视为字节而不是dwords。
mov cl, [eax] ;save value of last marker into a temp register
mov dl, [ebx] ;save value of first marker into a temp register
mov [ebx], cl ;save value in ecx to the memory location pointed by ecx
mov [eax], dl ;save value in edx to the memory location pointed by eax
此代码无法正确退出程序。调用核心的EXIT函数。
whileReverseEnd:
popa
leave
ret
由于 readstring 使用enter 0,0
,您需要在leave
和popa
之间添加匹配的ret
。
在 strlen 中,不使用pusha
会更容易。那样EAX可以退货!
strlen:
enter 0,0
push ecx
push ebx
mov eax, prompt1 ; <-- Change this to stringlabel
下一行可能有拼写错误。将 sb 更改为sub
。
sb eax, ebx ;subtract the final positions
答案 1 :(得分:-1)
;***************************************************
;
; Reversing a string in 8086 ALP
;
; code by Akshay Rajput
;****************************************************
section .data
msg db "microprocessor"
len: equ $-msg
section .bss
rstring resb 14
section .code
global _start
_start:
%macro write 2
mov eax,4
mov ebx,1
mov ecx,%1
mov edx,%2
int 80h
%endmacro
%macro read 2
mov eax,3
mov ebx,0
mov ecx,%1
mov edx,%2
int 80h
%endmacro
mov esi,msg
mov ecx,14
add esi,len-1
mov edi,rstring
AGAIN:mov eax,[esi]
mov [edi],eax
dec esi
inc edi
LOOP AGAIN
write rstring,14
mov eax,1
int 80h