如果我让你对这个问题感到困惑,我很抱歉,但我不知道更好地描述它
我正在尝试编写一个NASM程序来反转字符串。
我有3个函数:strlen,readstring和asm_main
readstring:从用户输入读取并将其存储在保留空间“inputstring”
中 push ebp ; setup routine
mov ebp, esp
;;;;;;;;;;;;;;;;;;;;;;;;;;
mov eax, message
call print_string ; print"please enter your string message"
mov eax, 3 ; read
mov ebx, 1 ; from standard input
mov ecx,inputstring; store at memory locaton inputstring
mov edx, 100 ; 100 byte
int 0x80
mov eax, inputstring
;;;;;;;;;;;;;;;;;;;;;
pop ebp
ret
稍后,我使用另一个子程序“strlen”来获取用户输入的长度
问题是:
在我的主程序中,我有两个寄存器保存开头和最后一个字符的地址。所以ecx持有开始,ebx持有最后一个字符
让我说我输入“abcde”,
所以我将$ ecx指向字符串的开头,$ ebx指向最后一个字符(即e \ n)。我的问题是,当我交换ecx和ebx时,我是否用最后一个字符(e / n)交换整个字符串(abcde)?
或者我是否将第一个字符(a)与最后一个字符(e / n)交换?
当我尝试在GDB中打印出每个寄存器的内容时。
ecx:abede / n
ebx:e / n
所以我将整个字符串与最后一个字符交换,这绝对不是我想要的。那么我哪里做错了???有人可以给我一个暗示吗?
这是我的代码
%include "asm_io.inc"
segment .data
message db "Please enter your string message: ", 0xA,0
formatin db "%d", 0xA
segment .bss
inputstring: resb 100
segment .text
global asm_main
extern printf
extern scanf
**asm_main**:
enter 0, 0
pusha
;;;;;;;;;;;;;;;;;;;;;;;;
call readstring
mov ecx, eax ; now ecx contains the begin address
call strlen ; when return, eax will hold the length
push eax ; we need eax in the loop
; use edi as temporary pointer
; use ebx to point to the last char
mov ebx, 0 ;initialize ebx to 0
add ebx, ecx ; ebx = ecx now, ebx points to the beginning
add ebx, eax ; ebx = ecx + eax, now it points to then end
sub ebx, 1 ; ebx = ecx +eax -1, now it points to the
; last char
while:
cmp ebx, ecx ; cmp end , begining
jle exitWhile
mov edi, [ebx] ; temp = *end
mov eax,[ecx] ; *end = *begining
mov [ebx], eax
mov [ecx], edi ; *beginning = temp
inc ecx
dec ebx
jmp while
exitWhile:
pop eax
popa
mov eax, 0
leave ; missing this line will cause segmentation
; fault, why?
ret
**readstring**:
push ebp ; setup routine
mov ebp, esp
;;;;;;;;;;;;;;;;;;;;;;;;;;
mov eax, message
call print_string
mov eax, 3 ; read
mov ebx, 1 ; from standard input
mov ecx,inputstring; store at memory locaton inputstring
mov edx, 100 ; 100 byte
int 0x80
mov eax, inputstring
;;;;;;;;;;;;;;;;;;;;;
pop ebp
ret
**strlen**:
push ebp
mov ebp, esp
push esi
;;;;;;;;;;;;;;;;;;;;;
mov esi, ecx ; now esi contains the address of string
mov edx, 0 ; edx will be int i
loop:
mov al, [esi] ; al
cmp al, 0xA ; check if al holds an ASCII new line
je exitLoop
inc esi
inc edx
cmp esi, inputstring+100; see if esi is pointing past the end
; of the 100 reserved byte
jl loop
exitLoop:
;;;;;;;;;;;;;;;;;;;;
mov eax, edx
pop esi
pop ebp
ret
答案 0 :(得分:0)
由于您正在为作业使用32位寄存器,因此您一次交换四个字符。你交换" abcd"与" e \ n ??" (其中??是字符串后面的两个字节)。对ASCII字符使用8位寄存器:
while:
cmp ebx, ecx ; cmp end , begining
jle exitWhile
mov al,[ebx]
xchg al,[ecx]
mov [ebx],al
inc ecx
dec ebx
jmp while
exitWhile: