JavaScript Menu, DHTML Menu Powered By Milonic
комсомольск-на-амуре
komcity.ru
новости форум поиск
login   pass 
  ФОРУМ / КОМПЬЮТЕРЫ И МОБИЛЬНЫЕ ТЕХНОЛОГИИ / Assembler
  создать новую тему написать сообщение  
18:21 28 мая 2009
тема Assembler наверх
 
  _Djin_
сообщений: 78
Отправить письмо через веб-интерфейс
Народ помогите кто чем может нужно написать прогу для перевода из Восьмеричной системы счисления в Двеннадцатиричную на Асме....Вот Есть код для 8 to 16, а надо 8 to 12
title a10.exe -- from 8 to 16
code segment
assume cs:code
main: mov si,8
again: mov bx,0
mov dl,'?'
call d1
mov cx,6
next: call kbin
cmp al,' '
je back
mov ah,0
and al, 00001111b
mov di, ax
mov ax, bx
mul si
add ax, di
mov bx, ax
loop next
back: mov dl,'='
call d1
mov dx,bx
call hexw
mov dl,'H'
call d1
call crlf
jmp again
;---------- subroutines --------------
d1 proc
mov ah,2
int 21h
ret
d1 endp
kbin proc near
mov ah,1
int 21h
ret
kbin endp
hex proc near
mov ax,cs
; push ds
mov ds, ax ; set ds=cs
push dx
mov bx, offset t1
mov al, dl
clc
shr al,1
shr al,1
shr al,1
shr al,1
xlatb ; translate
mov dl, al
call d1
pop ax
and al, 00001111b
xlatb ; translate
mov dl, al
call d1
; pop ds
ret
t1 db '0123456789ABCDEF'
hex endp
hexw proc near
mov di, dx
mov dl, dh
call hex
mov dx, di
call hex
mov dl,' '
call d1
ret
hexw endp
crlf proc near
mov dl, 10
call d1
mov dl, 13
call d1
ret
crlf endp
code ends
end main

 
13:50 1 июня 2009
тема Assembler наверх
 
  -sc-
сообщений: 529
Отправить письмо через веб-интерфейс
если еще актуально, я немного откомментировал код и написал процедурку duodec (переводит число в 12-рич. сис. и выводит его на экран)
вот измененный код (процудуру hex оставил на память :) )
код не компилировал и не отлаживал, написал как есть, поэтому может и не работать
title a10.exe -- from 8 to 12
code segment
assume cs:code
main:
mov si,8 ; 8 так как исходная с-ма восьмеричная (потом будем умножать на 8)
again:
mov bx,0 ; здесь будет введенное число после перевода его из ascii в число
mov dl,'?'
call d1 ; выводим вопрос
mov cx,6
next:
call kbin ; считываем символ
cmp al,' ' ; если пробел, то конец ввода
je back
mov ah,0 ; дальше переводим ascii символ, в число (например код '1' равен 0x31 )
and al, 00001111b ; теперь ax = 1 (сначало было например 0x31)
mov di, ax ; временно запомним
mov ax, bx ; временно запомним (ax = bx = 0 на первой итерации цикла)
mul si ; умножим на si (=8) на ax (=0), ax = 0
add ax, di ; сложим с введенным числом (0 + 1)
mov bx, ax ; запомним результат
loop next ; перейдем на считывание следующего символа
back:
mov dl,'=' ; выводим =
call d1
mov dx,bx
call hexw ; переводим двух байтовое число в hex (и выводим в станд.вывод)
mov dl,'H'
call d1 ; выводим H
call crlf ; перевод строки
jmp again ; все сначала (новое число)
;---------- subroutines --------------
d1 proc ; пишем в станд. вывод
mov ah,2
int 21h
ret
d1 endp
kbin proc near ; читаем со станд. ввода
mov ah,1
int 21h
ret
kbin endp
hex proc near ; переводим один символ (один байт) в 16-чную с-му
mov ax,cs
; push ds
mov ds, ax ; set ds=cs
push dx
mov bx, offset t1
mov al, dl
clc
shr al,1
shr al,1
shr al,1
shr al,1
xlatb ; translate
mov dl, al
call d1
pop ax
and al, 00001111b
xlatb ; translate
mov dl, al
call d1
; pop ds
ret
t1 db '0123456789ABCDEF'
hex endp
duodec proc near ; переводим один символ (один байт) в 12-чную с-му
mov ax,cs
mov ds, ax ; set ds=cs
mov bx, offset t2 ; в bx адрес начала буфера
; переводим число в ascii (в 12-чной сис-ме и складываем в буфер в обратном порядке)
label0:
mov ax, dx ; в ax число
cdq
idiv 12 ; делим число на 12 (получаем ah - остаток, al - частное)
cmp ah, 9 ; сравним, если число <= 9, то прибавим '0' иначе 'a'
jle label1
add ah, 87 ;число - 10 + 'a'
mov byte ptr [bx], ah ; запишем в буфер
jmp label2
label1:
add eax, 48 ; число + '0'
mov byte ptr [bx], ah ; запишем в буфер
label2:
add bx, 1 ; увеличим указатель на буфер на 1
mov dx, al ; запишем частное от деления
cmp dx, 0 ; проверим на 0 и если не равно, еще один цикл
jg label0
; выводим буфер на печать в обратном порядке (на печать выходит в прямом)
label4:
sub bx, 1 ; уменьшим указатель на буфер, так сейчас он указывает за последнуюю букву
xor dx, dx
mov dl, byte ptr [bx] ; в dl буква по указателю
call d1 ; выводим букву в станд. вывод (на экран например)
mov ax, offset t2
cmp ax, bx ; проверим не дошли ли мы до начала буфера
jne label4 ; цикл еще раз
ret
bf db ' '; буфер, достаточный для размещения строки результата
duodec endp
hexw proc near ; переводим два символа (dx содежит число)
call duodec
mov dl,' '
call d1
ret
hexw endp
crlf proc near ; перевод строки
mov dl, 10
call d1
mov dl, 13
call d1
ret
crlf endp

 
11:35 2 июня 2009
тема Assembler наверх
 
  _Djin_
сообщений: 78
Отправить письмо через веб-интерфейс
что то не работает, выдает несколько ошибок, в том числе и в последней строчке которой не существует, может кто еще чем помочь может???? Все равно большое спасибо!

 
16:10 2 июня 2009
тема Assembler наверх
 
  -sc-
сообщений: 529
Отправить письмо через веб-интерфейс
а чем компилируешь, tasm, masm? какая ось? я тоже может попробую, если время и асм найду.
только сейчас заметил, строчка
bf db ' '; буфер, достаточный для размещения строки результата
ужалась, между ' ' должно быть много пробелов, штук 20 например (чтобы число влезло)

 
18:20 3 июня 2009
тема Assembler наверх
 
  _Djin_
сообщений: 78
Отправить письмо через веб-интерфейс
компилирую тасмом...что то все равно ничего не получается..(((

 
15:35 6 июня 2009
тема Assembler наверх
 
  -sc-
сообщений: 529
Отправить письмо через веб-интерфейс
Наконец-то появилось время (суббота :) ) Если все еще актуально, вот работающая версия (под Windows).
Компилировал Tasm32(5.3), отлаживал odbg(1.10)
Скомпилировать проще всего так:
1. Распаковать Tasm в какую-нибудь дир., например d:\bin\tasm
2. В дир. Examples создать дир. duodec
3. В дир. duodec создать файл duodec.asm с исходным кодом
4. Тут же (в duodec) создать файл duodec.def
5. B тут же создать файл make.bat
Для компиляции выполнить make.bat
После запуска программа выводит знак '?'. Дальше можно ввести 8-ричное число (цифры должны быть меньш 8) После ввода числа нужно ввести пробел. Программа распечатает число в 12-рич. сис. счисл.
Пример работы:
D:\bin\tasm\EXAMPLE\duodec>duodec.exe
? 0 = 0
D:\bin\tasm\EXAMPLE\duodec>duodec.exe
? 1 = 1
D:\bin\tasm\EXAMPLE\duodec>duodec.exe
? 7 = 7
D:\bin\tasm\EXAMPLE\duodec>duodec.exe
? input error: digit must be less or equal 7!
D:\bin\tasm\EXAMPLE\duodec>duodec.exe
? 10 = 8
D:\bin\tasm\EXAMPLE\duodec>duodec.exe
? 14 = 10
Как видим, переход на десяток в восмеричной системе происходит на 8-ми (10 = 8)
А переход на 10 в 12-рич. системе происходит при 12 (14 в восмерич.) (14 = 10)
Файл duodec.def:
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
HEAPSIZE 65536
STACKSIZE 65536
Файл make.bat:
@echo off
cls
..\..\BIN\tasm32 /mx /m4 /z duodec.asm
..\..\BIN\tlink32 -x -V4.0 -Tpe -ap -c duodec.obj,duodec,,,duodec.def
if errorlevel == 1 goto failure
del *.obj
echo duodec.exe created
goto end
:failure
echo error!
:end
pause
Файл duodec.asm:
.386
.model flat, stdcall
locals
includelib ..\..\LIB\imp32i.lib
include ..\..\INCLUDE\w32.inc
;
extrn printf : PROC
extrn _getch : PROC
extrn _putch : PROC
;
.DATA
buf db 32 dup(?)
quest db "? ", 0
fmtS db "%s", 0
fmtD db "%d", 0
equal db " = ", 0
errM db"input error: digit must be less or equal 7!", 0
.DATA?
;
.CODE
start:
pushad ; сохраним регистры
mov si, 8 ; так как исходная с-ма восьмеричная (потом будем умножать на 8 )
mov ebx, 0 ; здесь будет введенное число после перевода его из ascii в число
call printf, offset quest ; выводим '?'
add esp, 4 ; восстановим стек
next:
mov eax, 0 ; обнулим eax
call _getch ; ожидаем ввода символа
cmp ax, 20h ; если пробел, то конец ввода
je endinput ; переходим на преобразование числа
mov ah, 0 ; дальше переводим ascii символ, в число (например код '1' равен 0x31 )
and al, 00001111b ; теперь ax = 1 (сначало было например 0x31)
mov di, ax ; временно запомним
cmp ax, 7 ; если введенная цифра больше 7, то ошибка
jle cont ; переход на продолжние работы
call printf, offset errM ; печатаем сообщение об ошибке
add esp, 4 ; восстанавливаем стек
jmp exit ; переход на конец программы
cont:
call printf, offset fmtD, eax ; печатаем очередную введенную цифру
add esp, 8 ; восстанавливаем стек
mov ax, bx ; временно запомним bx
mul si ; умножим ax на 8 (si = 8)
add ax, di ; сложим с уже введенным числом (накапливаем сумму)
mov bx, ax ; запомним результат
loop next ; перейдем на считывание следующего символа
endinput:
call printf, offset equal ; выводим знак '='
add esp, 4 ; восстановим стек
mov edx, ebx ; введенное число в dx
call duodec ; преобразуем и печатаем число в 12-рич. систему
exit:
popad ; восстановим регистры
call ExitProcess, 0 ; вызов завершения программы (в Windows)
ret ; конец программы
;
;proc - подпрограмма, перевод числа в dx в 12-чную с-му и вывод на экран
duodec:
mov ebx, offset buf ; в bx адрес начала буфера
; переводим число в ascii (в 12-чной сис-ме и складываем в буфер в обратном порядке)
label0:
mov si, 12 ; будем делить на 12
mov ax, dx ; число в ax
sub dx, dx ; преобразуем AX в двойное слово в AX:DX
div si ; делим число на 12 (получаем dx - остаток, ax - частное)
cmp dl, 9 ; сравним, если число <= 9, то прибавим '0' иначе 'a'
jle label1
add dl, 87 ;число - 10 + 'a'
mov byte ptr [ebx], dl ; запишем букву в буфер
jmp label2
label1:
add dl, 48 ; число + '0'
mov byte ptr [ebx], dl ; запишем букву в буфер
label2:
add bx, 1 ; увеличим указатель на буфер на 1
mov dx, ax ; частное в dx
cmp dx, 0 ; проверим на 0 и если не равно, еще один цикл
jg label0
; выводим буфер на печать в обратном порядке (на печать выходит в прямом)
label4:
sub bx, 1 ; уменьшим указатель на буфер, так сейчас он указывает за последнуюю букву
xor edx, edx ; обнуляем edx
mov dl, byte ptr [ebx] ; в dl буква по указателю
call _putch, edx ; выводим букву в станд. вывод (на экран например)
add esp, 4 ; восстанавливем стек
mov eax, offset buf ; в ax начало буфера
cmp eax, ebx ; проверим не дошли ли мы до начала буфера
jne label4 ; если нет, цикл еще раз
ret ; конец подпрограммы
END start


 
10:43 8 июня 2009
тема Assembler наверх
 
  _Djin_
сообщений: 78
Отправить письмо через веб-интерфейс
Огромнейшее спасибо, пробую откомпилировать...

 
12:11 10 июня 2009
тема Assembler наверх
 
  _Djin_
сообщений: 78
Отправить письмо через веб-интерфейс
-sc-, Что то не могу откомпилировать...говорит ошибка...может как нибудь Экзэшник перекинуть можно??? на мыло например?

 
18:02 10 июня 2009
тема Assembler наверх
 
  _Djin_
сообщений: 78
Отправить письмо через веб-интерфейс
Так вроде откомпилировал, но вот после нажатия пробела....вылетает из проги...что это может быть???

 
18:18 10 июня 2009
тема Assembler наверх
 
  _Djin_
сообщений: 78
Отправить письмо через веб-интерфейс
так вроде как прогу запустить разобрался, только вот приходится для перевода каждого числа заново запускать прогу...почему выходит? и почему включая семерку и выше не переводит??


 
05:58 12 июня 2009
тема Assembler наверх
 
  -sc-
сообщений: 529
Отправить письмо через веб-интерфейс
Семерку она переводит 7 = 7, и 77 тоже переведет. В восьмеричной системе одна цифра не может быть больше 7. Т.е. 77 нормально, а 78 уже нет. Про системы счисления немного написано в вики. Искать гуглом по словам: wiki системы счисления.
Программку написал только для перевода одного числа, но если надо больше то вот. Весь текст не привожу,только три кусочка и куда вставить. Чтобы выйти, нужно ввести "неправильный" символ, например Enter.
добавим строчку crlf ... вот так:
errM db "input error: digit must be less or equal 7!", 0
crlf db 13, 10, 0
.DATA?
добавми строчку again: вот так:
.CODE
start:
pushad ; сохраним регистры
again:
mov si, 8 ; так как исходная с-ма восьмеричная (потом будем умножать на 8 )
и еще пару строчек вот так:
call duodec ; преобразуем и печатаем число в 12-рич. систему
call printf, offset crlf ; перевод строки
add esp, 4 ; восстановим стек
jmp again
exit:

 
06:04 12 июня 2009
тема Assembler наверх
 
  -sc-
сообщений: 529
Отправить письмо через веб-интерфейс
Насчет проблем компиляции не знаю. Никаких не было. Путь к tasm32 нужно прописать в переменную окружени path. Tasm у меня такой
D:\bin\tasm\EXAMPLE\duodec>tasm32
Turbo Assembler Version 5.0 Copyright (c) 1988, 1996 Borland International
Винда XP. Tasm брал на wasm.ru wasm'е в разделе компиляторы Tasm5+.

 
09:49 15 июня 2009
тема Assembler наверх
 
  _Djin_
сообщений: 78
Отправить письмо через веб-интерфейс
Все спасибо большое, не знаю что бы я без вас делал, все сдал....зачет поставил!!! :-)) :-)

 
01:47 17 июня 2009
тема Assembler наверх
 
  Мастер
сообщений: 147
Вопрос не касается первоначального сообщения, но касается ассемблера.
Сразу скажу, что это программа учебная, используется ассемблер для DOS, конкретнно - tasm 3.0
Условие такое: имеется две переменные
var1 db '1234567890$'
var2 db '0987654321$'
В определенный момент необходимо присвоить переменной var1 значение переменной var2. Делаю так:
mov AX, offset var1
mov var2, AX
При компиляции выдает ошибку: Operand types do not match, указывается номер второй строки, в которой пытаюсь в переменную записать из регистра....
Как правильно сделать копирование одной переменной в другую?

 
04:42 18 июня 2009
тема Assembler наверх
 
  -sc-
сообщений: 529
Отправить письмо через веб-интерфейс
Насколько я понял, под присвоить здесь имеется ввиду скопировать var2 в var1 (побайтно). Это может сделать следующий код (простой, так как учебный :) ):
;
mov ax, offset var1 ; в ax указатель на переменную var1
mov bx, offset var2 ; в bx указатель на переменную var2
label1:
mov cl, byte ptr [bx] ; в cl загружаем значение (байт) из адреса в bx (var2)
mov byte ptr [ax], cl ; значение в cl записываем (байт) в адрес в ax (var1)
; (таким образом скопировали 1 байт)
add ax, 1 ; увеличиваем указатель на 1, так чтобы он указывал на следующий байт переменной var1
add bx, 1 ; увеличиваем указатель на 1, так чтобы он указывал на следующий байт переменной var2
cmp cl, '$' ; сравниваем с $ (концом последовательности)
jne label1 ; делаем еще один цикл, если не достигли конца
;
После выполнения данного кода переменная var1 будет такой:
var1 db '0987654321$'

 
17:43 18 июня 2009
тема Assembler наверх
 
  Мастер
сообщений: 147
mov byte ptr [ax], cl - вот на эту строчку ругается, Illegal indexing mode
UPD
Из описаний ошибок tasm
 
Illegal indexing mode
(Недопустимый режим индексации)
Команда содержит операнд, использующий недопустимую комбинацию регистров. Например
mov al,[si+ax]
Для всех процессоров, за исключением 80386, допустимыми комбинациями индексных регистров являются следующие: BX, BP, SI, DI, BX+SI, BX+DI, BP+SI, BP+DI.
Как бы изменить код так, чтобы работал?

 
15:20 21 июня 2009
тема Assembler наверх
 
  -sc-
сообщений: 529
Отправить письмо через веб-интерфейс
ну вроде компилятор подсказывает, что вместо ax, bx нужно использовать si, di. Поэтому пробуем такой код:
mov di, offset var1
mov si, offset var2
label1:
mov al, byte ptr [si]
mov byte ptr [di], al
add di, 1
add si, 1
cmp al, '$'
jne label1

 
18:22 23 июня 2009
тема Assembler наверх
 
  Мастер
сообщений: 147
Спасибо, помогло!

 
06:02 19 июля 2009
тема Assembler наверх
 
  SD
сообщений: 321
Отправить письмо через веб-интерфейс
Извините, что влез... так поздно. Вот и ответ на вопрос "Чему учат программистов в Комсе?" :-(
Тема последнего задания, как я понимаю, что-то вроде "изучение строковых команд". Я бы её не принял, показывает незнание набора инструкций (не отностися к -sc- который давно забыл). Есть однобайтные команды загрузки с автоинкрементом источника (si) и приёмника (di)
cld ; сбрасывем флаг направления
label1:
lodsb
stosb
cmp al, '$'
jne label1


 
20:15 3 ноября 2009
тема Assembler наверх
 
  Мастер
сообщений: 147
Нет, там было не про строковые команды, приведенный вопрос был лишь эпизодом в курсовой :) Сейчас подучил, спрашивать такое не стал бы, да.

 
   
  создать новую тему написать сообщение  
Сервер развивается и поддерживается редакцией еженедельника «Наш город»
Отдел рекламы: (4217) 20-10-07; adver@komcity.ru
Правила использования материалов
    Яндекс цитирования Программирование: 2002—2004  — Технодизайн
2005—2013  — "Наш город"