0
votes

So I have to strings s1 and s2 and I have two obtain the string d that contains the maximum numbers for each of the positions of s1 and s2.

For example:

S1: 1, 3, 6, 2, 3, 10

S2: 6, 3, 11, 1, 2, 5

D: 6, 3, 11, 2, 3, 10

So this is the code

bits 32
global start
extern exit,printf
import exit msvcrt.dll 
import printf msvcrt.dll
segment data use32 class=data
    format db "%s",0
    s1 db "1","3","6","2","3","10"
    l equ $-s1
    s2 db "6","3" ,"11","1","2", "5"
    d times l db 0

segment code use32 class=code
start:
    mov esi,0
    mov edi,0
    cld
    Repeta:
        mov al,[s1+esi]
        mov bl,[s2+esi]
        cmp al,bl
        jg et1
        mov[d+edi],bl
        inc edi
        inc esi
        jmp et2
        et1:
            mov[d+edi],al
            inc edi
            inc esi
        et2:    
    cmp esi,l
    jne Repeta
    push d
    push format
    call[printf]
    add esp,4*2

push dword 0 
call [exit]

The problem is that when it reaches a double digit element(10 or 11) it takes only the first digit(1) and compares it with the number from the other string on the same position and after that it takes the second digit and compares it with the next number from the other string. How can I solve this?

1
If your strings were single-digit numbers, SSE2 pmaxub would do exactly what you need in one instruction: a per-element max with unsigned byte elements (the ASCII codes for the 0-9 digits are in order and consecutive). With strings that aren't 4, 8, or 16 bytes long, you'd need to either pad the output buffer or store in parts, though.Peter Cordes
Are you sure you wrote your db directive correctly? It looks like your string is supposed to include commas, but the way you wrote it is exactly equivalent to s1: db "1362310" This is obviously ambiguous. Are you sure it wasn't supposed to be db 1, 3, 6, 2, 3, 10 (array of byte elements) or db "1, 3, 6, 2, 3, 10" (string containing commas)?Peter Cordes
Well, it says that it should be a string of bytes.Doull Owen
Are you sure it means string in a computer-language sense, and not sequence or array of bytes? That seems more likely than assigning a string-parsing and decimal string->binary int conversion task in assembly language. The phrase "of bytes" very strongly implies array to me. Ask your instructor for clarification, but I think s1: db 1, 3, 6, 2, 3, 10 is what you're supposed to be working with, so the elements are fixed width single byte integers. (And not ASCII strings at all).Peter Cordes

1 Answers

0
votes

it says that it should be a string of bytes

The phrase "of bytes" very strongly implies array to me. Ask your instructor for clarification, but I think s1: db 1, 3, 6, 2, 3, 10 is what you're supposed to be working with, so the elements are fixed width single byte integers. (And not ASCII strings at all).

This means you can use a simple pairwise max like SSE2 pmaxub (for unsigned bytes) or SSE4.1 pmaxsb (for signed bytes).

segment data use32 class=data
    format db "%s",0
    s1 db 1, 3, 6, 2, 3, 10
    l equ $-s1
    s2 db 6, 3, 11, 1, 2, 5

    d times l db 0

start:
    movq   xmm1, [s1]       ; load all 6 elements, plus 2 bytes past the end but that's ok.  We ignore those bytes
    movq   xmm2, [s2]
    pmaxub xmm1, xmm2       ; element-wise vertical max

    ;but avoid storing outside of 6-byte d
    movd   [d], xmm1        ; store first 4 bytes of the result
    pextrw [d+4], xmm1, 2   ; store bytes 4 and 5 (word 2 of xmm1 = 3rd word)

    ...  ; the result isn't a string, you can't print it with printf.

For byte counts that aren't a multiple of 2, e.g. if l was 7, you could use this instead of pextrw:

psrldq  xmm1, 3                ; bring the data you want to store down into the low 4 bytes of the register
movd    [d+4], xmm1            ; 4-byte store that overlaps by 1

BTW, I realize that you're intended to loop over the elements 1 byte at a time. Maybe use cmp cl, al / cmovg eax, ecx / mov [edi], al to store what was originally in cl if cl > al (signed), otherwise store what was originally in al.

I think your loop structure is a bit broken, because you have one path that doesn't store to d. You always need to store to d, regardless of which source was greater.