I don't know where my code for reversal of a string gone wrong but code below hangs my computer.
1. Without rev$ macro
Include /masm32/include/masm32rt.inc
.data
buff1 dB "Hello World"
.data?
buff2 dB 50 dup(0)
.code
Start:
Mov eax.len(buff1)
Label1:
Mov bl,byte PTR buff1[eax-1]
Mov ecx,0
Mov byte PTR buff2[ecx],bl
Inc ecx
Dec eax
Jnz label1
Mov byte PTR buff2[ecx],0 ; null terminated string
Invoke StdOut, addr buff2
Inkey
Invoke ExitProcess,0
End start
I don't know how to code with the use of rev$ macro . Plz anyone help. The problem comes while displaying results. The above code
Shows no errors but hangs my computer without displaying anything.
Post your code. Make sure it's complete with includes etc, and comment what you have done so far. Explain what doesn't work (error messages...).
Ravi,
There is a logic to how its done, if you create a string that is 7 characters long,
1 2 3 4 5 6 7
swap
1 and 7
2 and 6
3 and 5
4 cannot be swapped.
on 6 characters
swap
1 and 6
2 and 5
3 and 4
Have a look at the library module, "szrev.asm".
It is doing a bit more so you don't have to change the original string but it shows you how the strig reverse is coded.
These are what you call "in place" operations. You could do it by allocating a buffer and doing a reverse copy from the source to the destination.
http://abreojosensamblador.epizy.com/Productos/AOE/Codigos/Cap07/MOVSCM1.asm
Ravi,
Here is a simpified version of an "in place" string reverse.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
raviRev PROTO pstr:DWORD
.data
ravi db "Hi, my name is Ravi",0
numz db "1234567890",0
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
inkey
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
LOCAL rval :DWORD
cls
print ADDR ravi,13,10,13,10
invoke raviRev,ADDR numz ; reverse the number above
mov rval, eax
print rval,13,10
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
raviRev proc pstr:DWORD
LOCAL ln :DWORD ; length
LOCAL hl :DWORD ; half length
push ebx ; save EBX
invoke szLen,pstr
mov ln, eax ; get full string length
shr eax, 1 ; get integer half length of string
mov hl, eax ; store it in variable
mov edx, pstr
add edx, ln ; get end character address
sub edx, 1 ; sub 1 to get end char
mov eax, pstr ; eax has start char
lp:
mov bl, [eax] ; load start char
mov cl, [edx] ; load end char
mov [eax], cl ; reverse char pair
mov [edx], bl
add eax, 1 ; increment start char
sub edx, 1 ; decrement end char
sub hl, 1 ; sub 1 from half length
jnz lp ; loop back if its not zero
mov eax, pstr ; return the address in eax
pop ebx ; restore EBX
ret 4 ; balance the stack by 4 bytes
raviRev endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
include \masm32\include\masm32rt.inc
.data
My$ db "1234567890", 0
.code
start:
mov esi, offset My$
lea edi, [esi+len(esi)]
push esi
.Repeat
mov al, [esi] ; get char from left end
dec edi
mov dl, [edi] ; get char from right end
mov [esi], dl
mov [edi], al
inc esi
.Until esi>=edi
pop esi
inkey esi
exit
end start
Thank you JJ sir for your help. Sorry for my inconvenience previously. Can you tell me where my code gone wrong. The code up on running shows a hanging console window and shows a debug messagebox. I'm trying to do simple programs all by myself. But assembly is not like C.
Quote from: Ravi Kiran on May 06, 2021, 05:10:44 PMCan you tell me where my code gone wrong. The code up on running shows a hanging console window
Ravi,
Your code above assembles with several errors, so it definitely did not show a console window, because it never ran.
Be precise when asking for help: tell us what exactly went wrong! Copy the error messages, and paste them here.
I'll give you some hints:
- assembly is case-sensititive. Label1 is
not label1, inkey is not Inkey
- error A2008: syntax error in instruction means that a dot is not a comma
No such problem for mov/Mov and invoke/INVOKE, but macros like inkey and len() are indeed case-sensitive.
Correct your code until it assembles without errors, then correct the position of the Mov ecx,0 line. If you are stuck, we'll continue here. But, please, with full code and detailed comments...
Now it was working sir. The below code perfectly reversed the string.
include \masm32\include\masm32rt.inc
.data
buff1 db "Hello World",0
.data?
buff2 dB 50 dup(0)
.code
start:
lea esi,buff1
mov eax,len(esi)
mov ecx,0
label1: mov bl,byte PTR buff1[eax-1]
mov byte PTR buff2[ecx],bl
Inc ecx
dec eax
jnz label1
mov byte ptr buff2[ecx],0 ; Null terminated string
print " The reversed string is: "
invoke StdOut, addr buff2
inkey " "
exit
end start
The above program didn't worked when mov eax,len( buff1) instruction is used instead of lea esi,buff1 , mov eax, len(esi) .
Why is this happening? Is'nt buff1 the name of an array which carries the starting address of the array. I don't understand this change.
Quote from: Ravi Kiran on May 07, 2021, 01:27:03 AMThe above program didn't worked when mov eax,len( buff1) instruction is used instead of lea esi,buff1 , mov eax, len(esi) .
Why is this happening? Is'nt buff1 the name of an array which carries the starting address of the array. I don't understand this change.
buff1 is the name, but it's not the start address. Use
offset buff1 instead:
start:
mov eax,len(offset buff1)
xor ecx, ecx ; shorter than mov ecx,0
label1:
mov bl,byte PTR buff1[eax-1]
mov byte PTR buff2[ecx],bl
Inc ecx
dec eax
jnz label1
Btw you will not become a good assembly programmer if you don't learn to write
comments.
Above I had posted an in-place reversal. Your version copies all chars to a new buffer - that is OK. Here is a variant of your approach:
include \masm32\include\masm32rt.inc
.data
buff1 db "[Hello World]",0
.data?
buff2 dB 50 dup(0)
buff3 dB 50 dup(0)
.code
start:
mov eax,len(offset buff1)
xor ecx, ecx ; shorter than mov ecx,0
label1:
pushad
print "+"
popad
mov bl,byte PTR buff1[eax-1]
mov byte PTR buff2[ecx],bl
Inc ecx
dec eax
jnz label1
mov byte ptr buff2[ecx],0 ; Null terminated string
print " The reversed string is: "
invoke StdOut, addr buff2
print chr$(13, 10)
mov eax,len(offset buff1)
xor ecx, ecx ; shorter than mov ecx,0
label2:
pushad
print "+"
popad
dec eax
mov bl,byte PTR buff1[eax] ; get char from right end
mov byte PTR buff3[ecx],bl ; put char to left end
mov bl,byte PTR buff1[ecx] ; get char from left end
mov byte PTR buff3[eax],bl ; put char to right end
inc ecx
cmp ecx, eax ; eax and ecx meet in the middle
js label2
;mov byte ptr buff2[ecx],0 ; Null terminated string
print " The reversed string is: "
invoke StdOut, addr buff3
print chr$(13, 10, 10)
exit
end start
The pushad, print, popad sequence is a simple way to monitor what your proggie is doing.
strrev provided by the C run-time library :
include \masm32\include\masm32rt.inc
.data
string db 'This is a test',0
.code
start:
invoke crt__strrev,ADDR string
invoke StdOut,eax
invoke ExitProcess,0
END start
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strrev-wcsrev?view=msvc-160
As a sport task, I have made a win32 example. I have used some polindromes to test it. The dutch phrase impressed me on how can it be compressed in only one word. Though, as I look at it, it seems that "ss" and "s" are switched.
https://es.wikipedia.org/wiki/Palíndromo#En_neerlandés
Thanks, I added your algo to the timings testbed (http://masm32.com/board/index.php?topic=9350.msg102586#msg102586) :thumbsup: