assembly 请告诉我为什么我的文本不对齐?

xam8gpfp  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(118)

这个问题是关于“链对齐”的。
根据以下规则和指定内存位置的传递结果,对等于输入字符串的函数void align_str(char \*output, char \*in, unsigned int size, int align)进行编程。
由输出参数赋值。

  • 链的输出长度是相同的大小。
  • 参数对齐指定对齐方式,如下所示:0 =左,1 =中,2 =右,对于其他值,结果未定义。
  • 在左对齐的情况下,第一个字符永远不会是空格。
  • 在右对齐的情况下,最后一个字符永远不会是空格。
  • 链条以所需长度的间隙完成。
  • 在中心对齐的情况下,在链的开始和结束处相等地填充空间。
  • 假设输入仅包含范围为0x20到0x7e(包括0x20和0x7e)的ASCII表字符。
  • 如果不能满足所有条件(例如不带开闭空格的文本长度大于size),则结果为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

这个函数是从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
n3ipq98p

n3ipq98p1#

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 开始在终止零后面写入空格。这些空间永远不会出现!

左对齐

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---->

居中对齐

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-->

右对齐

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---->

·在左对齐的情况下,第一个字符永远不会是空格。
·在右对齐的情况下,最后一个字符永远不会是空格。
如果输入的两端包含一个或多个空格字符,则任务希望您删除这些字符:

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

尽管此处计算的StrLen为22,但丢弃前导和尾随空格导致长度为16。此外,您现在要复制的字符从RSI + 2开始(因为有2个前导空格)。
祝你好运!

相关问题