无法在汇编中进行重叠块传输
Unable to do overlap block transfer in Assembly
我用汇编语言 (nasm) 编写了一个程序来进行重叠块传输,即,如果我的数组之一包含“10、20、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
您的重叠副本工作正常。不起作用的是您调用显示例程的方式。
首先,当您将 10 字节数组的十六进制表示复制到其中时,您只为输出分配了 10 个字节(因此您需要 20 个字节!)
其次,您只打印了 10 个字节。由于我们将长度更改为 20,因此您也应该将打印长度更改为 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
函数时已经得到正确的长度。
我用汇编语言 (nasm) 编写了一个程序来进行重叠块传输,即,如果我的数组之一包含“10、20、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
您的重叠副本工作正常。不起作用的是您调用显示例程的方式。
首先,当您将 10 字节数组的十六进制表示复制到其中时,您只为输出分配了 10 个字节(因此您需要 20 个字节!)
其次,您只打印了 10 个字节。由于我们将长度更改为 20,因此您也应该将打印长度更改为 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
函数时已经得到正确的长度。