# Given a byte string S of length l, obtain the string D of length l-1 as D(i) = S(i) * S(i+1)

Given a byte string S of length l, obtain the string D of length l-1 as D(i) = S(i) * S(i+1) (each element of D is the product of two consecutive elements of S).

here is my code.

bits 32

global start

extern exit
import exit msvcrt.dll

segment data use32 class=data
s db 1, -3, 4, 7 ; declaring the string of bytes s
l equ \$ - s - 1 ; compute the length of the string l - 1
d times l dw 0 ; reserve l bytes for the destination string and initialize it
segment code use32 class=code
start:
mov ecx, l

mov esi, 0

jecxz end_prog
repeat_this:
mov al, [s + esi] ; in al - the element on the esi position
mov dh, [s + esi + 1] ; in dh - the element after the esi position
imul dh ; multiplying consecutive terms
mov [d + esi], ax; put the result in d
inc esi ; incrementing esi to go to the next position
loop repeat_this

end_prog:

push dword 0
call [exit]


my question is did I make a mistake by declaring d times l dw 0 since I know that a byte * byte = word? Is everything else okay or should I pay attention to some details that I'm missing?

• You're asking whether d is supposed to be declared with dw element-size, but the quoted program-description doesn't clearly say, so as far as I can tell there's no way for us to know that. Was there originally a larger explanation or some additional context that contains such information? – harold Nov 6 '20 at 16:49
• no, I just wanted to know if that would be considered a mistake even if it doesn't say. also I didn't know if my program was entirely correct because of that fact. so I wanted to check and asked someone more experienced than me. – just1frustredstudent Nov 6 '20 at 16:54
• If this is homework, please tag it as such. – Reinderien Nov 6 '20 at 17:52
• fixed it @Reinderien, I'm sorry! :c – just1frustredstudent Nov 6 '20 at 17:54
• It's OK :) For a relatively new user this is a quite-good question for CR. – Reinderien Nov 6 '20 at 17:55

# Inconsistent addressing of d

d is an array of 2-byte elements (d times l dw 0) and mov [d + esi], ax indexes into it with esi as the offset. However, esi is increased by 1 every iteration, so the resulting access pattern is that the stores keep stepping half on top of the previous store, shown by such a diagram: (storing -3, -12 and 28 in sequence)

FD FF
F4 FF
1C 00


This is possible to do, but probably unintentional.

Normally my recommendation would be to increase the register by 2 in the loop, but esi is also used to index s so that won't work. You can change the store to double esi though, for example:

mov [d + esi*2], ax


Or,

mov [d + esi + esi], ax


If you change d to be an array of bytes then the store should be mov [d + esi], al, with the original address but storing only 1 byte. Storing overlapping words would put the right data in d, but it's strange and stores a stray byte just after the end of d.

# Calling exit

exit performs C library termination procedures, but the C library runtime environment wasn't used or even initialized (this code is in start, not main), so it's not necessary. It makes more sense to call ExitProcess (kernel32.dll), or just return (that does not work on Linux, but this is a Windows program and there it does work).

# The loop instruction

loop is not great, it has some niche uses but typically it should be avoided. jecxz by contrast is OK, just unusual.

# Minor things

The best way to zero esi isn't mov esi, 0, it's xor esi, esi, unless the flags must not be affected.

The two loads of the current and next element of S could be merged into a single word load, if you want. For example mov ax, [s + esi] followed by imul ah.

• thank you for the detailed comment for the program! we were taught to use loop and jecxz, but I'll try to look for better alternatives in the future! – just1frustredstudent Nov 6 '20 at 17:53
• because it forces the content of esi to be 0. – just1frustredstudent Nov 6 '20 at 17:57
• @Reinderien that's also a link to the reasons, but perhaps the double-formatting is not super clear – harold Nov 6 '20 at 17:59
• @harold Oh! I missed that - thank you! – Reinderien Nov 6 '20 at 17:59