proc num2dec near
; Параметры: AX - число ES:DI-конец буфера для записи строки
std ; Запись справа налево для STOSB
mov bx,10 ; Делитель
diving:
xor dx,dx ; Чтобы избежать переполнения при делении
div bx ; AX=частное DX=остаток
xchg ax,dx
or al,'0'
stosb ; AX -> [ES:DI] ; DEC DI
mov ax,dx
or ax,ax ; Частное было равно нулю?
jnz diving ; Нет-продолжить цикл
ret
endp num2dec
показ ASCII кода
:( народ, помогите новичку,нужно написать программу, которая в веденной строчке инвентирует символы по ASCII таблице т.е. если введенного символа ASCII код = 97 (буква а маленькая) то инвентируем её: 127 - 97 = 30. Полученые значения ASCII кот. меньше 31 выводим на екран как ASCII код. Например ввели строку ab3, на экране появится 3029L. ... заранее всем откликнувшимся благодарен.
Не совсем понятно значение слова "инвертировать". Можно поподробнее? И в чём конкретно проблема? В составлении алгоритма или в его реализации и в какой части?
сорри забыл уточнить .. написать нужно на языке ассемблера . Сама проблема в реализации, а точнее не выходит сделать ,чтоб выводил код ASCII символа :)
Видимо проблема в процедуре преобразования числа в строку. Попробуй эту процедуру.
Код:
model small
.Stack 100h
.Data
str1 db 13, 10, 'strochka: $'
str2 db 13, 10, 'otvet: $'
str3 db 256 dup(0)
.Code
;-------------------------------
vpisat proc
mov ah, 06h
int 21h
ret
endp vpisat
;-------------------------------
vpisat_str proc
mov ah, 09h
int 21h
ret
endp vpisat_str
;-------------------------------
proc prochest
xor bx, bx
jmp sk_cikl
sk_nazad:
cmp bx, 0000h
je sk_cikl
dec bx
mov dl, 08h
call vpisat
mov dl, 20h
call vpisat
mov dl, 08h
call vpisat
sk_cikl:
mov ah, 07h
int 21h
cmp al, 00h
jne sk_1
mov ah, 07h
int 21h
jmp sk_cikl
sk_1:
cmp al, 0dh
je sk_konec
cmp al, 08h
je sk_nazad
cmp bx, 00ffh
je sk_cikl
cmp al, 20h
jb sk_cikl
mov dl, al
call vpisat
inc bx
mov cl, 127 ; zagoniajem v CL 127 (poslednij ASCII)
mov ch, al ; v CH zapisyvajem ASCII kod nastojashego simvola
sub cl, ch ; CL - CH
mov al, cl ; staryj ASCII simvola meniajem na novyj, poluchenij ASCII
mov [si][bx], al
jmp sk_cikl
sk_konec:
mov [si], bl
ret
endp prochest
;-------------------------------
proc vpisat_otv
xor bx, bx
ir_cikl:
cmp bl, [si]
je ir_konec
inc bx
mov dl, [si][bx]
call vpisat
jmp ir_cikl
ir_konec:
mov dl, 0dh
call vpisat
mov dl, 0ah
call vpisat
ret
endp vpisat_otv
;-------------------------------
nachialo:
mov ax, @data
mov ds, ax
lea dx, str1
call vpisat_str
lea si, str3
call prochest
lea dx, str2
call vpisat_str
call vpisat_otv
mov ah, 4ch
int 21h
end nachialo
.Stack 100h
.Data
str1 db 13, 10, 'strochka: $'
str2 db 13, 10, 'otvet: $'
str3 db 256 dup(0)
.Code
;-------------------------------
vpisat proc
mov ah, 06h
int 21h
ret
endp vpisat
;-------------------------------
vpisat_str proc
mov ah, 09h
int 21h
ret
endp vpisat_str
;-------------------------------
proc prochest
xor bx, bx
jmp sk_cikl
sk_nazad:
cmp bx, 0000h
je sk_cikl
dec bx
mov dl, 08h
call vpisat
mov dl, 20h
call vpisat
mov dl, 08h
call vpisat
sk_cikl:
mov ah, 07h
int 21h
cmp al, 00h
jne sk_1
mov ah, 07h
int 21h
jmp sk_cikl
sk_1:
cmp al, 0dh
je sk_konec
cmp al, 08h
je sk_nazad
cmp bx, 00ffh
je sk_cikl
cmp al, 20h
jb sk_cikl
mov dl, al
call vpisat
inc bx
mov cl, 127 ; zagoniajem v CL 127 (poslednij ASCII)
mov ch, al ; v CH zapisyvajem ASCII kod nastojashego simvola
sub cl, ch ; CL - CH
mov al, cl ; staryj ASCII simvola meniajem na novyj, poluchenij ASCII
mov [si][bx], al
jmp sk_cikl
sk_konec:
mov [si], bl
ret
endp prochest
;-------------------------------
proc vpisat_otv
xor bx, bx
ir_cikl:
cmp bl, [si]
je ir_konec
inc bx
mov dl, [si][bx]
call vpisat
jmp ir_cikl
ir_konec:
mov dl, 0dh
call vpisat
mov dl, 0ah
call vpisat
ret
endp vpisat_otv
;-------------------------------
nachialo:
mov ax, @data
mov ds, ax
lea dx, str1
call vpisat_str
lea si, str3
call prochest
lea dx, str2
call vpisat_str
call vpisat_otv
mov ah, 4ch
int 21h
end nachialo
;-------------------------------
данная програма делает в принципе то что надо... только вот проблема в том что она на экран выводит символы, независимо от того АСКИ код меньше 31 или нет. так вот нужно както зделать так чтобы при записи символа в память она записывала не символ а десятичное число АСКИ этого символа. :)
Пока могу сказать, что длинновата программа для такой задачи. И процедуры не стоит использовать, если вызываешь только один раз. Комментариев побольше стоит, а то сам через неделю забудешь, что писАл.
;--------------
Для ввода строки думаю лучше использовать 0ah функцию 21 прерывания, будет проще.
программа может и длинноватая но такая какая должна быть. процедуры там нужны для считывания символов с клавы. вобщем вопрос не в том как укоротить или как убрать процедуры, а в том как распечатать АСКИ код.теперь же она делает все как надо... только без аски кода...
Так я же дал процедуру перевода числа в строку... В чем тогда проблема?
и еще, аски-код обязательно десятичном виде вsводить?
и третий вопрос, а расценивать аскикоды как знаковые числа обязатедьно? т.е. инвертировать имено 127-аски, а не обычным not
1 . я считал 31 -десятичным
2. Вывожу аски-код в шетнпдцетиричном формате
3. инвертирую именно вычитанием
Код:
.model tiny
.code
org 100h
begin:
jmp start
buf db 100, 100 dup (?)
msg db 'Enter the string: ', 0dh, 0ah, '$'
msg2 db 0dh,0ah, 'Inverted string',0dh,0ah, '$'
tabl db '0123456789abcdef'
start:
push cs
pop ds
entr:
mov ah,09h
mov dx, offset msg
int 21h
mov ah,0ah
mov dx,offset buf
int 21h
xor cx,cx
mov cl, buf[1]
test cl,cl
je entr
mov di,2
mov ah,09h
mov dx,offset msg2
int 21h
invrt:
xor dx,dx
mov dl,buf[di]
inc di
mov al,7fh
sub al,dl
cmp al,31
jl asci
mov dl,al
mov ah,02h
int 21h
loop invrt
ret
asci:
mov bx,offset tabl
push ax
shr al,4
xlatb
mov dl,al
mov ah,02h
int 21h
pop ax
and al,0fh
xlatb
mov dl,al
mov ah,02
int 21h
loop invrt
ret
end begin
.code
org 100h
begin:
jmp start
buf db 100, 100 dup (?)
msg db 'Enter the string: ', 0dh, 0ah, '$'
msg2 db 0dh,0ah, 'Inverted string',0dh,0ah, '$'
tabl db '0123456789abcdef'
start:
push cs
pop ds
entr:
mov ah,09h
mov dx, offset msg
int 21h
mov ah,0ah
mov dx,offset buf
int 21h
xor cx,cx
mov cl, buf[1]
test cl,cl
je entr
mov di,2
mov ah,09h
mov dx,offset msg2
int 21h
invrt:
xor dx,dx
mov dl,buf[di]
inc di
mov al,7fh
sub al,dl
cmp al,31
jl asci
mov dl,al
mov ah,02h
int 21h
loop invrt
ret
asci:
mov bx,offset tabl
push ax
shr al,4
xlatb
mov dl,al
mov ah,02h
int 21h
pop ax
and al,0fh
xlatb
mov dl,al
mov ah,02
int 21h
loop invrt
ret
end begin
В прикрепленом архиве исходник+откомпилиная прога.
Товарищ просил не писать за него прогу, а помочь в её написании. Тем самым ты оказываешь ему медвежью услугу. Если человек не будет ничего делать сам, не будет пытыться разобраться в новом для него занятии, он никогда ничему не научится.
ну звиняйте. разогналса маленько. но если он пробелма была только в выводе аски-кода, то в моей реализации она решена и ее не трудно оттудаво забрать проигнорировав все остальное. темболее как я понял оно у него даже написано
Спасибо. только чем вот ее компайлить? и было бы любезно комментов добавить в то место где код аски печатает :) и распечатка в десятичном виде нужна. еще раз сенкью :)
т.е. имея в BX -начало таблицы с символами шестнадцетиричных числ, в результате мы получим вместо числа в AL - символ этого числа. но вывод здесь шестнадцетиричный
когда делаю tasm он мне эрор кидает: (48) rotate count out of range. может скайп имеешь?
рогу запустил... только вот как бы в десятичном распечатать? сижу блин голову ломаю... ниче придумать не могу :(
Код:
.model tiny
.code
org 100h
begin:
jmp start
buf db 100, 100 dup (?)
msg db 'Enter the string: ', 0dh, 0ah, '$'
msg2 db 0dh,0ah, 'Inverted string',0dh,0ah, '$'
tabl db '0123456789abcdef'
num db 2 dup(30h) ,'$'
start:
push cs
pop ds
entr:
mov ah,09h
mov dx, offset msg ;вывод строки приглашения
int 21h
mov ah,0ah
mov dx,offset buf ;ввод строки
int 21h
xor cx,cx
mov cl, buf[1] ;считываем дляну введеной строки
test cl,cl ; если она 0
je entr ;повторяем ввод
mov di,2 ; смещение на первывй ссимвол буфера
mov ah,09h
mov dx,offset msg2
int 21h
invrt:
xor dx,dx
mov dl,buf[di] ;читаем символ
inc di
mov al,7fh
sub al,dl ;вычитаем из 127(7fh)
cmp al,31 ;сравнение с 31
jl asci ;меньше? прыгаем
mov dl,al ;нет?
mov ah,02h ;выводим символ
int 21h
loop invrt ;следуйщий символ буфера
ret
asci:
xor dx,dx ;если меньше 31
push cs
pop es
push di ;сохраняем смещение символа в буффере
mov di,offset num+1 ;устанавливаем смещение на второй символ переменой куда запишем преобразованое число
std ;di=1
asci2:
xor ah,ah
mov bl,10
div bl ;делим число на 10
push ax
add ah,30h ;ah - остаток добавляем 30h, что бы получить аскикод цифры
mov al,ah
stosb ;записуем в буфер num
pop ax
test al,al ;частоне 0?
jnz asci2 ;нет? продолжаем преобразование
mov ah,09
mov dx,offset num ;да? выводим строку спреобразованым числом
int 21h
pop di ;вотсанавливаем смещение внутри исхродного буфера
loop invrt ;следуйщий символ
ret
end begin
.code
org 100h
begin:
jmp start
buf db 100, 100 dup (?)
msg db 'Enter the string: ', 0dh, 0ah, '$'
msg2 db 0dh,0ah, 'Inverted string',0dh,0ah, '$'
tabl db '0123456789abcdef'
num db 2 dup(30h) ,'$'
start:
push cs
pop ds
entr:
mov ah,09h
mov dx, offset msg ;вывод строки приглашения
int 21h
mov ah,0ah
mov dx,offset buf ;ввод строки
int 21h
xor cx,cx
mov cl, buf[1] ;считываем дляну введеной строки
test cl,cl ; если она 0
je entr ;повторяем ввод
mov di,2 ; смещение на первывй ссимвол буфера
mov ah,09h
mov dx,offset msg2
int 21h
invrt:
xor dx,dx
mov dl,buf[di] ;читаем символ
inc di
mov al,7fh
sub al,dl ;вычитаем из 127(7fh)
cmp al,31 ;сравнение с 31
jl asci ;меньше? прыгаем
mov dl,al ;нет?
mov ah,02h ;выводим символ
int 21h
loop invrt ;следуйщий символ буфера
ret
asci:
xor dx,dx ;если меньше 31
push cs
pop es
push di ;сохраняем смещение символа в буффере
mov di,offset num+1 ;устанавливаем смещение на второй символ переменой куда запишем преобразованое число
std ;di=1
asci2:
xor ah,ah
mov bl,10
div bl ;делим число на 10
push ax
add ah,30h ;ah - остаток добавляем 30h, что бы получить аскикод цифры
mov al,ah
stosb ;записуем в буфер num
pop ax
test al,al ;частоне 0?
jnz asci2 ;нет? продолжаем преобразование
mov ah,09
mov dx,offset num ;да? выводим строку спреобразованым числом
int 21h
pop di ;вотсанавливаем смещение внутри исхродного буфера
loop invrt ;следуйщий символ
ret
end begin
благодарствую :) коментов только нехватает... хочеться понять смысл и ход действия ;) Лоне Вульф - родина тебя не забудет :))
добавил комменты. всегда пожалуйста)
перед тем как выводить символ мы считываем строку.
нам может понадобиться потом переделать программу так чтобы строка считывалась с конца. в нашем случае нам нужно поменять три строки :)
mov di, 2 ; смещение на первывй ссимвол буфера
mov dl,buf[di] ;читаем символ
inc di ;
на
mov di, (сюда последний символ т.е. длина строки buf[1]) ; смещение на последний ссимвол буфера
mov dl, buf[di] ;читаем символ
dec di ;уменьшаем счетчик.
вопрос в том как этот buf[1] загнать в DI регистр?? =\
Код:
xor ax,ax
mov al,buf[1]+1
mov di,al
;а дальше как ты и написал
mov dl,buf[di]
dec di
mov al,buf[1]+1
mov di,al
;а дальше как ты и написал
mov dl,buf[di]
dec di
только проследи чтобы в тот момент регистр ax(или другой, какой возьмеш) не использывалса, или был сохранен, если в нем что-то важное.
ну попробовал так сделать... кидает ошибку о несовместимых типах. В этой строке - mov di,al :-\
Код:
xor ax,ax
mov al,buf[1]+1
mov di,ax
;а дальше как ты и написал
mov dl,buf[di]
dec di
mov al,buf[1]+1
mov di,ax
;а дальше как ты и написал
mov dl,buf[di]
dec di
может из-за того что АХ пожже используется? :-\ может какой другой регистр попробывать? не АХ?
------------
нашел решение =)
xor ax,ax
mov al,buf[1]
add al, 1
mov di,ax
а дальше как ты и написал =) все работает :) супер ;)
но у меня не выходит его выкинуть на экран :( help...
sasadabest, мне кажется, что тебе стоит прочитать первую-вторую главую любого букваря по ассемблеру и вопросы пропадут сами собой :)
[SIZE="1"]//добвалено через 5 часов[/SIZE]
Сэнкс , уже не нужно