Reputation: 21
I am very new to Assembly and I am trying to program the task, which requires to divide input up to 80 characters and modify it every 24 bits (3 blocks of 8 bits) by substiting bits in the following order 5 -> 15 -> 20 -> 1-> 6 (5th bit goes to the place of 15 bit, 15 bit goes to the place of 20 bit and so on). However, I get an relative jump out of range error when calling loop after subsituting final bit 5->15. Could somebody please advise what's wrong in this code? I would very appreciate some help here. Thanks in advance.
.model small
ASSUME CS:kodas, DS:duomenys, SS:stekas
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
stekas segment word stack 'STACK'
dw 400h dup (00) ; stekas -> 2 Kb
stekas ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
duomenys segment para public 'DATA'
pranesimas1:
db 'Enter row up to 80 symbols'
naujaEilute:
db 0Dh, 0Ah, '$' ; tekstas ant ekrano
pranesimas2:
db 'Entered symbols are grouped every 24 bits: ', 0Dh, 0Ah, '$'
pranesimas3:
db '24 bitu bloko bitai sukeiciami pagal schema: 5 -> 15 -> 20 -> 1-> 6: ', 0Dh, 0Ah, '$'
pranesimas4:
db 'Amount of zero bits is:', 0Dh, 0Ah, '$'
buferisIvedimui:
db 81, 00, 83 dup (0)
a:
db 00
b:
db 00
c:
db 00
bit0:
dw 0000
bit1:
dw 0000
buferisAtsakymui:
sk1 db 00
sk2 db 00
sk3 db 00
db 0Dh, 0Ah,'$'
duomenys ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LOCALS @@
kodas segment para public 'CODE'
spausdinkBaitoDvKoda proc near
push dx
push ax
push cx
push bx
mov cx, 0008
mov dh, al
mov bl, 10000000b
@@ciklas_pagal_cx_nuo_8:
mov dl, dh
and dl, bl
dec cl
shr dl, cl
shr bl, 1
inc cl
add dl, '0'
mov ah, 02
int 21h
loop @@ciklas_pagal_cx_nuo_8
pop bx
pop cx
pop ax
pop dx
ret
spausdinkBaitoDvKoda endp
;--------------------------------------------------------
spausdinkTarpa proc near
push dx
push ax
mov dl, ' '
mov ah, 02
int 21h
pop ax
pop dx
ret
spausdinkTarpa endp
;-------------------------------------------------------
skaiciuokBituSk proc near
push dx
push ax
push cx
push bx
mov cx, 0008
mov dh, al
mov bl, 10000000b
@@ciklas_pagal_cx_8:
mov dl, dh
and dl, bl
dec cl
shr dl, cl
shr bl, 1
inc cl
xor ax, ax
mov al, dl
add word ptr bit0, ax
loop @@ciklas_pagal_cx_8
mov cl, byte ptr[buferisIvedimui + 1]
mov al, cl
mov bl, 8
mul bl
sub ax, word ptr bit0
mov word ptr bit1, ax
pop bx
pop cx
pop ax
pop dx
ret
skaiciuokBituSk endp
;-------------------------------------------------------
pradzia:
mov ax, seg duomenys
mov ds, ax
mov ah, 09
mov dx, offset pranesimas1
int 21h
mov ah, 0Ah
mov dx, offset buferisIvedimui
int 21h
mov ah, 09
mov dx, offset naujaEilute
int 21h
mov ah, 09
mov dx, offset naujaEilute
int 21h
mov ah, 09
mov dx, offset pranesimas2
int 21h
xor cx, cx
mov cl, byte ptr[buferisIvedimui + 1]
xor ax, ax
mov al, cl
mov bl, byte ptr 3
div bl
mov cl, al
xor bx, bx
mov bx, 2
@@ciklas1_pagal_cx_nuo_baitu_skaiciaus:
mov al, byte ptr[buferisIvedimui + bx + 2]
mov byte ptr c, al
call SpausdinkBaitoDvKoda
call spausdinkTarpa
mov al, byte ptr[buferisIvedimui + bx + 1]
mov byte ptr b, al
call SpausdinkBaitoDvKoda
call spausdinkTarpa
mov al, byte ptr[buferisIvedimui + bx]
mov byte ptr a, al
call SpausdinkBaitoDvKoda
call spausdinkTarpa
; 5 -> 15 -> 20 -> 1-> 6
;1->6
mov ah, byte ptr a
and ah, 00000010b
and byte ptr a, 10111101b
shl ah, 1
shl ah, 1
shl ah, 1
shl ah, 1
shl ah, 1
or byte ptr a, ah
;20->1
mov dl, byte ptr c
and dl, 00010000b
and byte ptr c, 11101111b
shr dl, 1
shr dl, 1
shr dl, 1
or byte ptr a, dl
;15->20
mov ah, byte ptr b
and ah, 10000000b
and byte ptr b, 01111111b
shr ah, 1
shr ah, 1
shr ah, 1
or byte ptr c, ah
;5->15
mov ah, byte ptr a
and ah, 00100000b
and byte ptr a, 11011111b
shl ah, 1
shl ah, 1
or byte ptr b, ah
mov al, byte ptr a
mov byte ptr[buferisIvedimui + bx], al
mov al, byte ptr b
mov byte ptr[buferisIvedimui + bx + 1], al
mov al, byte ptr c
mov byte ptr[buferisIvedimui + bx + 2], al
inc bx
add bx, 2
loop @@ciklas1_pagal_cx_nuo_baitu_skaiciaus
mov ah, 09
mov dx, offset naujaEilute
int 21h
mov ah, 09
mov dx, offset naujaEilute
int 21h
mov ah, 09
mov dx, offset pranesimas3
int 21h
xor cx, cx
mov cl, byte ptr[buferisIvedimui + 1]
xor ax, ax
mov al, cl
mov bl, byte ptr 3
div bl
mov cl, al
xor bx, bx
mov bx, 2
@@ciklas2_pagal_cx_nuo_baitu_skaiciaus:
mov al, byte ptr[buferisIvedimui + bx + 2]
call SpausdinkBaitoDvKoda
call spausdinkTarpa
mov al, byte ptr[buferisIvedimui + bx + 1]
call SpausdinkBaitoDvKoda
call spausdinkTarpa
mov al, byte ptr[buferisIvedimui + bx]
call SpausdinkBaitoDvKoda
call spausdinkTarpa
inc bx
add bx, 2
loop @@ciklas2_pagal_cx_nuo_baitu_skaiciaus
;Calculating total amount of null bits
xor cx, cx
mov cl, byte ptr[buferisIvedimui + 1]
mov bx, 2
@@ciklas1_pagal_cx_nuo_baitu_skaiciaus1:
mov al, byte ptr[buferisIvedimui + bx]
call skaiciuokBituSk
inc bx
loop @@ciklas1_pagal_cx_nuo_baitu_skaiciaus1
mov ax, word ptr bit1
mov dx, 0000
mov bx, word ptr 10
div bx
add dl, '0'
mov byte ptr sk3, dl
mov dx, 0000
div bx
add dl, '0'
mov byte ptr sk2, dl
mov dx, 0000
div bx
add dl, '0'
mov byte ptr sk1, dl
mov ah, 09
mov dx, offset naujaEilute
int 21h
mov ah, 09
mov dx, offset naujaEilute
int 21h
mov ah, 09
mov dx, offset pranesimas4
int 21h
mov dx, offset buferisAtsakymui
mov ah, 09
int 21h
mov ah, 4ch
int 21h
mov ah, '?'
kodas ends
end pradzia
Upvotes: 1
Views: 1749
Reputation: 14409
loop @@ciklas1_pagal_cx_nuo_baitu_skaiciaus
causes the error. LOOP
can only perform short jumps (–128 to +127 bytes). In this case you cannot replace it by
dec cx
jne @@ciklas1_pagal_cx_nuo_baitu_skaiciaus
(see https://stackoverflow.com/a/32769524/3512216), because the jump is yet too wide for a conditional jump (jne
). For a remedy look at https://stackoverflow.com/a/32626759/3512216.
You can let TASM do the transformation. Just place a line with JUMPS
to the beginning of the text. TASM transforms the invalid loop to (label names added by me):
loop LOOP
jmp ENDLOOP
LOOP:
jmp @@ciklas1_pagal_cx_nuo_baitu_skaiciaus
ENDLOOP:
Upvotes: 1