My intention with this code is, to count how many characters a null terminated string has, and the return value is stored at AX.
The problem is with line (mov bx, [ebp+4+ax])
Very good. But do you know why? The problem is, you're getting a WORD value, not a BYTE. So, for example. When you have the string "Hello", you're reading both the "H" and the "e" into bx and testing for 0. Then the next go-around, you're putting the "l" and "l" into bx and testing for 0 again. Finally, you put the "o" and the null terminator into bx and test for 0, but it doesn't find zero because the "o" is present! So, instead, lets try this using bytes instead.
char_count:
push bp
mov bp, sp
mov ax, 0 ; character offset
loop_start:
mov bl, [bp+4+ax] ; bl = arg1[ax]
cmp bl, 0 ; compare if arg1[ax] = null terminate
jz end_loop ; if previous compare true, jump to end of loop
inc ax ; if not, go back to loop start
jmp loop_start
end_loop:
mov sp, bp
pop bp
ret
I've made three minor changes to this code.
1. Since this code is running in DOS, I changed over to 16-bit register names. Not sure if it really matters, but it just looks cleaner. Also, this is probably required since you are addressing using [bp+
4+ax] which means you're procedure expects arguments come after the IP and BP present on the stack.
2. I made "bx" into a "bl" so that we are only reading a byte value.
3. You pop the BP register before you update the SP register, I put these in the right order. really don't need to do this because SP isn't modified, but whatever.
Now, if you don't mind, I'm going to ASSume something here. You probably aren't wanting to access arg1[ax], rather you're probably going to be sending a pointer to the procedure as arg1. There is a slight difference in this.
char_count:
push bp
mov bp, sp
mov si, [bp+4] ; get address from arg1
loop_start:
mov bl, [si] ; bl = *arg1
cmp bl, 0 ; compare if *arg1 is null terminated
jz end_loop ; if previous compare true, jump to end of loop
inc si ; arg1++
jmp loop_start ; if not, go back to loop start
end_loop:
mov sp, bp
pop bp
ret
There might be another small "problem" where the program will segfault, this will most likely be the case if you don't adhere to the CDECL calling convention which you seem to be using. But I won't ASSume that much and just hope that you remember to add sp, 2 in your callee.
Regards,
Bryant Keller