无法在装配中执行重叠块传输

时间:2016-01-16 17:09:25

标签: assembly nasm x86-64

我用汇编语言(nasm)创建了一个程序来进行重叠块传输,即,如果我的一个数组包含' 10,30,30,40,50'(没有引号),那么重叠后例如,2个元素,我得到的数组应包含' 10,20,10,20,30,40,50'(不带引号)。但我的问题是,当我显示我的结果数组时,它只显示' 10,20,10,20,30'(没有引号)。我无法弄清楚这个问题。下面显示的是我的代码。任何帮助将不胜感激。

%macro disp 2                               ; Display macro
mov rax,1
mov rdi,1
mov rsi,%1
mov rdx,%2
syscall
%endm

%macro accept 2                             ; Accept Data
mov rax,0
mov rdi,0
mov rsi,%1
mov rdx,%2
syscall
%endm

global _start           

section .data                               ; Data Section
arr db 10h,20h,30h,40h,50h
msg1: db "",10,"Input array is",10
len1: equ $-msg1
msg2: db "",10,"Output array is",10
len2: equ $-msg2
msg3: db "Enter the number to be overlapped",10
len3: equ $-msg3

section .bss                                ; Bss Section
arr1 resb 10
ar1 resb 10
ar2 resb 10
cn resb 2



section .text                               ; Text Section
_start:                                 ; Tell linker entry point

disp msg3,len3                                      
accept cn,2                         ; Accept No. of overlaps to be done from user

mov cl,[cn]                         ; Convert the cn from ASCII
sub cl,'0'                          ; to Decimal

mov rsi,arr
mov rdi,arr1


up: mov al,[rsi]                            ; Copy the contents from arr to arr1 for cn times
mov [rdi],al
inc rsi
inc rdi
dec cl
jnz up

mov rsi,arr                         ; Now copy the contents again from starting
mov cl,5

up_a:   mov al,[rsi]
mov [rdi],al
inc rsi
inc rdi
dec cl
jnz up_a

mov rsi,arr                         ; Convert to ASCII
mov rdi,ar1
mov rdx,5
call asci

mov rsi,arr1                            ; Convert to ASCII
mov rdi,ar2
mov rdx,10
call asci

disp msg1,len1
disp ar1,10

disp msg2,len2
disp ar2,10

mov rax,60
mov rdi,0
syscall


asci:  

up1:    mov al,[rsi]        ;Move the first element pointed by rsi into al register
    mov cl,2        ;The loop counter (there are 2 digits)

up2:    rol al,4        ; Rotate the contents of al 4 bits to the left. What were
                    ; previously the most significant bit will now be in
                    ; the least significant bit of al. This is done because
                    ; we want to print the most significant digit first. 
    mov bl,al       ; Make a copy of the rotated version of al.
    and al,0Fh      ; Keep the least significant bit of al and set all other
                    ; bits of al to 0.
    cmp al,09h      ; al will now be in the range 0..15. Is it greater than 9?
    ja dn1          ; ..if so, jump to dn1.
    add al,30h      ; al was in the range 0..9. The characters '0'..'9' are encoded as
                    ; 30h..39h in ASCII, so add 30h to convert into a character.
    jmp dn2         ; We're done with this case.

dn1:    add al,37h      ; al is in the range 10..15. The characters 'A'..'F' are encoded as
                        ; 41h..46h in ASCII, so add 37h to convert into a character.

dn2:   mov [rdi],al     ; Store the character in the buffer pointed to by rdi.
    mov al,bl       ; Restore al to the value it had right after the rol. So on the
                    ; next iteration we'll be processing what were originally the
                    ; second most significant bit, and so on.
    inc rdi         ; Increment the buffer pointer.
    dec cl          ; Decrement the loop counter.
    jnz up2         ; Repeat for all 2 digits.

        inc rsi         ; rsi now points to the next location
    dec rdx         ; Decrement the loop counter
    jnz up1         ; Repeat for all 5 array elements

ret

1 个答案:

答案 0 :(得分:2)

您的重叠副本工作正常。什么是行不通的是你如何调用显示例程。

首先,当您将10字节数组的十六进制表示复制到其中时,您只为输出分配了10个字节(因此您需要20个字节!)

其次,您只打印10个字节。由于我们将长度更改为20,因此您应将打印长度更改为。

以下是统一差异形式的变化:

--- orig.s  2016-01-16 19:55:33.268099503 +0000
+++ modified.s  2016-01-16 19:58:24.952600505 +0000
@@ -28,7 +28,7 @@
 section .bss                                ; Bss Section
 arr1 resb 10
 ar1 resb 10
-ar2 resb 10
+ar2 resb 20
 cn resb 2


@@ -77,7 +77,7 @@
 disp ar1,10

 disp msg2,len2
-disp ar2,10
+disp ar2,20

 mov rax,60
 mov rdi,0

尽管数组和数组的打印长度不正确,但在调用asci函数时,您已经有了正确的长度。