I'm new to assembly language programming and currently working on a simple program that prompts the user to enter a string, then reverses and displays it. However, I'm struggling to figure out how to display the message "The reversed string is:" and the reversed string on the same line.
Here's my current code:
section .bss
buffer resb 100
reversed_buffer resb 100
section .data
msg db "Please enter a string: ", 0
msgLen equ $ - msg
reverse_msg db "The reversed string is: ", 0
reverse_msg_len equ $ - reverse_msg
section .text
global _start
_start:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msgLen
int 0x80
mov eax, 3
mov ebx, 0
mov ecx, buffer
mov edx, 100
int 0x80
mov esi, eax
mov ecx, esi
dec ecx
mov esi, buffer
mov edi, reversed_buffer
reverse_loop:
cmp ecx, 0
jl end_reverse
mov al, [esi + ecx]
mov [edi], al
inc edi
dec ecx
jmp reverse_loop
end_reverse:
mov eax, 4
mov ebx, 1
mov ecx, reverse_msg
mov edx, reverse_msg_len
int 0x80
mov eax, 4
mov ebx, 1
mov ecx, reversed_buffer
mov edx, esi
int 0x80
mov eax, 1
xor ebx, ebx
int 0x80
Screenshot of the current output of my assembly program
Could someone guide me on how to modify this code so that the message "The reversed string is:" and the reversed string are displayed on the same line?
Thanks in advance for any help or suggestions!
mov eax, 4 mov ebx, 1 mov ecx, reversed_buffer mov edx, esi int 0x80
By the time your program executes this code, the ESI register contains the address of the buffer, so very much not the length of reversed string. Are you sure that this is the code that produced that screenshot?
sys_read
reports about the number of characters in EAX and reading from the terminal (stdin) the count in EAX includes the linefeed (10) that ends input. So for an input of HelloEnter you'd receive EAX=6, and the memory at buffer would contain the 6 bytes: 72, 101, 108, 108, 111, 10.
For the purpose of reversing, you don't want that newline byte to move to the front of the string.
Code that tries to reverse a string should be able to deal with an empty string. And so that the system prompt could re-appear on the left side of the screen, it would be nice to add another newline to the reversed string:
mov eax, 3
mov ebx, 0
mov ecx, buffer
mov edx, 100
int 0x80 ; -> EAX
xor EDI, EDI
dec eax ; Removing the newline code
jz .done ; Empty string
lea esi, [eax - 1] ; Offset to last character
.reverse:
movzx eax, byte [buffer + esi]
mov [reversed_buffer + EDI], al
inc EDI
dec esi
jns .reverse
.done:
mov byte [reversed_buffer + EDI], 10
inc EDI
mov eax, 4
mov ebx, 1
mov ecx, reverse_msg
mov edx, reverse_msg_len
int 0x80
mov eax, 4
mov ebx, 1
mov ecx, reversed_buffer
mov edx, EDI
int 0x80
This requires less memory and runs in fewer iterations. For a string shorter than 2 characters no changes are necessary, but else the loop has to run until both the offsets EBX and ECX meet each other in the middle of the string:
mov eax, 3
mov ebx, 0
mov ecx, buffer
mov edx, 100
int 0x80 ; -> EAX
mov EDI, eax ; (*)
xor ebx, ebx
cmp eax, 3
jb .done ; Empty string or just the one character
lea ecx, [eax - 2] ; Offset to last character
.reverse:
movzx eax, byte [buffer + ebx]
movzx edx, byte [buffer + ecx]
mov [buffer + ebx], dl
mov [buffer + ecx], al
inc ebx
dec ecx
cmp ebx, ecx
jb .reverse
.done:
mov eax, 4
mov ebx, 1
mov ecx, reverse_msg
mov edx, reverse_msg_len
int 0x80
mov eax, 4
mov ebx, 1
mov ecx, buffer
mov edx, EDI ; (*)
int 0x80