0

This question is about chain alignment.
Program the function void align_str(char \*output, char \*in, unsigned int size, int align) which equals the input string according to the following rules and the result of the delivery for the memory location specified.
Valued by the output argument.

  • The output length of chain is the same size.
  • Argument alignment specifies the alignment as follows: 0 = left, 1 = center, 2 = right, for other value, the result is undefined.
  • In case of left alignment, the first character is never a space.
  • In the case of right alignment, the last character is never a space.
  • The chain is completed with gaps to the required length.
  • In the case of center alignment, spaces are filled equally at the beginning and end of the chain.
  • Assume that the input contains only ASCII table characters from the range 0x20 to 0x7e (inclusive).
  • If all conditions cannot be met (e.g. the length of the text without opening and closing spaces is longer than size), the result is undefined.
 align_str:
    push rbp
    mov rbp, rsp
    push rbx
    push r12
    push r13

    ; Save registers on the stack

    mov r12, rdi ; r12 = output string
    mov r13, rsi ; r13 = input string
    mov ebx, edx ; ebx = output string size
    mov edi, ecx ; edi = alignment

    ; Calculate the length of the input string

    xor ecx, ecx ; ecx = 0
    xor edx, edx ; edx = 0

    strlen_loop:
        mov al, byte [r13 + rcx]
        cmp al, 0
        je end_strlen
        inc edx
        inc ecx
        jmp strlen_loop

    end_strlen:

    ; Calculate the number of spaces needed for alignment

    mov eax, ebx ; eax = size
    sub eax, edx ; eax = size - input string length
    jle align_done ; if less than or equal to 0, skip alignment

    cmp ebx, 0 ; check if output string size is greater than 0
    jle align_done ; if not, skip alignment

    pad_spaces:
        mov ebx, eax ; ebx = number of spaces to pad
        cmp edi, 0 ; check alignment
        je align_left
        cmp edi, 1
        je align_center
        cmp edi, 2
        je align_right
        ; Invalid alignment value
        jmp align_done

    align_left:
        jmp pad_left
    align_center:
        shr ebx, 1 ; divide by 2
        jmp pad_center
    align_right:
        jmp pad_right

    pad_right:
        mov rdx, r12 ; rdx = output string
        add rdx, rax ; rdx = output string + number of spaces to pad on the right
        mov byte [rdx], 0 ; null-terminate
        mov rdx, r12 ; rdx = output string
        mov rcx, r13 ; rcx = input string
        xor eax, eax ; eax = 0
        pad_right_loop:
            mov al, byte [rcx]
            mov byte [rdx], al
            inc rdx
            inc rcx
            cmp byte [rcx - 1], 0 ; check if we reached the end of the input string
            jne pad_right_loop
        xor ecx, ecx ; ecx = 0
        pad_right_center_loop:
            mov al, ' ' ; space character
            mov byte [rdx], al
            inc rdx
            inc ecx
            cmp ecx, ebx ; compare with the number of spaces to pad on the right
            jl pad_right_center_loop
        jmp align_done

    pad_center:
        mov rdx, r12 ; rdx = output string
        add rdx, rbx ; rdx = output string + number of spaces to pad
        mov byte [rdx], 0 ; null-terminate
        mov rdx, r12 ; rdx = output string
        mov rcx, r13 ; rcx = input string
        xor eax, eax ; eax = 0
        pad_center_loop:
            mov al, byte [rcx]
            mov byte [rdx], al
            inc rdx
            inc rcx
            cmp byte [rcx - 1], 0 ; check if we reached the end of the input string
            jne pad_center_loop
        xor ecx, ecx ; ecx = 0
        pad_center_right_loop:
            mov al, ' ' ; space character
            mov byte [rdx], al
            inc rdx
            inc ecx
            cmp ecx, ebx ; compare with the number of spaces to pad
            jl pad_center_right_loop
        jmp align_done

    pad_left:
        mov rdx, r12 ; rdx = output string
        add rdx, rbx ; rdx = output string + number of spaces to pad on the left
        mov byte [rdx], 0 ; null-terminate
        mov rdx, r12 ; rdx = output string
        mov rcx, r13 ; rcx = input string
        xor eax, eax ; eax = 0
        pad_left_loop:
            mov al, byte [rcx]
            mov byte [rdx], al
            inc rdx
            inc rcx
            cmp byte [rcx - 1], 0 ; check if we reached the end of the input string
            jne pad_left_loop
        jmp align_done

    align_done:
        pop r13
        pop r12
        pop rbx
        leave
        ret

And this function I call from C:

#include <stdio.h> 
#include <string.h> 
extern void align_str(char *output2, char *input2, unsigned int size, int alignment); 

int main() { 
  char input2[] = "Hello"; 
  char output2[10]; 
  unsigned int size = sizeof(output2); 
  int alignment = 1; 

  align_str(output2, input2, size, alignment); 
} // added by edit
2
  • 1
    Manipulating bytes, strings, arrays of bytes can be done in any language. There's no reason to "think in assembly" to figure out the algorithms for this. Do it in a language you know (preferably C) and when it is working, then all you have to do is transcribe your working C code into assembly, which means handling variables, for-loops, if-then, pointers, etc.. so you can do the same in assembly as the working C code. Commented Jun 21, 2023 at 19:02
  • 2
    It looks like "chain" just a mis-translation of "string" from another language. In English we use "string" to describe an array of characters. Commented Jun 21, 2023 at 19:04

1 Answer 1

3
   cmp edi, 0 ; check alignment
   je align_left
   cmp edi, 1
   je align_center
   cmp edi, 2
   je align_right
   ; Invalid alignment value
   jmp align_done

align_left:
   jmp pad_left
align_center:
   shr ebx, 1 ; divide by 2
   jmp pad_center
align_right:
   jmp pad_right

What is alignment?

Left-aligning some string in a buffer means that the padding goes on the right, and right-aligning some string in a buffer means the padding goes on the left. Your code does it the other way round and does not implement it correctly. eg. pad_right begins writing spaces behind a terminating zero. Those spaces will never show up!

Left-alignment

Input:  [My name0]                   Length is 7 (calculated)
Output: [.....................]      Size is 21 (provided)

Padding is Size - 1 - Length = 21 - 1 - 7 = 13
Output: [My name             0]
                <-----13---->

Center-alignment

Input:  [My name0]                   Length is 7 (calculated)
Output: [.....................]      Size is 21 (provided)

Padding is (Size - 1 - Length) / 2 = (21 - 1 - 7) / 2 = 6
Output: [      My name       0]
         <--6->       <--7-->

Right-alignment

Input:  [My name0]                   Length is 7 (calculated)
Output: [.....................]      Size is 21 (provided)

Padding is Size - 1 - Length = 21 - 1 - 7 = 13
Output: [             My name0]
         <-----13---->

• In case of left alignment, the first character is never a space.

• In the case of right alignment, the last character is never a space.

Should the input contain one or more space characters on its extremities, the task wants you to remove those:

Input:  [  An extra example    0]    Length is 16 (calculated)

Although here the calculated StrLen is 22, discarding the leading and trailing spaces leads to a length of 16. Also the characters that you will be copying now begin at RSI + 2 (because of the 2 leading spaces).

Good luck!

Sign up to request clarification or add additional context in comments.

1 Comment

please help me how to solve it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.