so ideally, I want this program to run the total number of characters that are in a msg. So for example "Hey there", there are 10 characters. It'll iterate 10 times. (I assume like C, you have to account for the space)
I hard-coded the values in because I'm having a difficult time figuring out how to have it read the number of characters within this string. I tried my code & it'll run once then wait for me to do something in the terminal. Or it'll seg fault (I've tried to do this about 100 times already, different ways everytime)
What am I doing wrong? I feel like it's something so simple I'm just overlooking! I tried to use the debugger to figure out what I'm doing wrong but I'm new to assembly so I'm a bit confused. So, if you could explain what the "computer" is doing that would help a lot!
For refrence this is my code:
section .text
global _start
_start:
mov edx, 13 ;;message to write
mov ecx, msg ;message length
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;trigger system call
mov ax, 13
loop_top:
cmp ax, 13
je loop_top
section .data
msg db 'Hello there!' ,0xa;the string of we want to pass
;;len equ $ - msg ;length of our string
CodePudding user response:
If you want to find the length of a string you can do the following.
First, make sure your string has an identifier at the end that makes you know that your string has ended, a null terminator is the default in most languages (in C for example).
str db "Hello, world!", 0x00
Then you need to iterate over this string until you reach 0x00
. You can do something like:
findStringLength:
mov cx, 0x00 ; lets keep a count on the character
iterate:
mov bx, str ; get the address of the string
add bx, cx ; add the character count that we kept
mov al, byte[bx] ; put the iterated character inside al
cmp al, 0x00 ; check if we reached the end of string
je endIteration ; end iteration if we did.
; do something with character in al
; ...
;
inc cx ; increase the iterator
jmp iterate ; loop
endIteration:
mov ax, cx ; return the length in ax
ret
This code is a template but you get the idea
CodePudding user response:
Like you said, it's a very simple thing you overlooked. Don't feel bad - I can't tell you how many times I did this.
Here's the problem:
mov ax, 13
loop_top:
cmp ax, 13
je loop_top
You set ax
to 13, and then you're checking over and over again until it's no longer 13. Since nothing is changing the value of AX, the je loop_top
is always taken and you just end up looping forever. And if somehow that branch isn't taken... You see, even though we've declared section .data
, the CPU isn't smart enough to know that's data and not instructions. The seg fault is happening likely because the CPU is attempting to execute the string itself, as though it were instructions. In assembly, the order you type things is taken very literally.
section .text
global _start
_start:
mov eax, len ;message length
loop_top:
push eax
mov edx, msg ;message to write
mov ecx, len ;message length
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;trigger system call
pop eax
dec al ;subtract 1 from AL
jnz loop_top ;if nonzero, do it again
;;your exit syscall needs to go here or you'll segfault.
section .data
msg db 'Hello there!' ,0xa;the string of we want to pass
len equ $ - msg ;length of our string
This isn't the most optimal way to do it, but it's a quick and dirty example.