我正在尝试在 NASM 中编写代码以将字符串反转到位,但我不断收到段错误。我发现一些人提出了类似的问题,但回答对我没有帮助。
继承人的代码:
%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