Страница 1 из 1
Код pascal -> ассемблер...
Добавлено: 07 окт 2009, 19:39
Dr_Grizzly
Всем привет! Пишу проект на трех языках программирования, и зашел в тупик на вроде бы простой процедуре, мне нужно на ассемблере написать процедурку, которая будет конвертировать римские цифры в нашу систему... накидал код на паскале вроде работает:
....
var
i,lastval, curval, result:integer;
tsifra: string;
....
procedure RomanToDec;
begin
result := 0;
lastval := 0;
for i := Length(tsifra) downto 1 do
begin
case UpCase(tsifra
) of
'C': curval := 100;
'D': curval := 500;
'I': curval := 1;
'L': curval := 50;
'M': curval := 1000;
'V': curval := 5;
'X': curval := 10;
else
writeln('Не правильное число');
end;
if curval < lastval then
Dec(Result, curval)
else
Inc(Result, curval);
lastval := curval;
end;
end;
....
А вот в ассемблере это написать не хаватает тяму... Ассемблер нужен из-за маленького размера скомпилированного файла.... Есть какие-нибудь соображения?
Заранее благодарен! 
Re: Код pascal -> ассемблер...
Добавлено: 07 окт 2009, 20:07
somewhere
Тебе весь код в асм? вместе с Writeln и прочей шнягой... или только функцию преобразования, которая в качестве параметра берет ссылку на строку и возвращает word?
Re: Код pascal -> ассемблер...
Добавлено: 08 окт 2009, 05:16
Dr_Grizzly
Впринципе достаточно самой функции. Как вывести предложение уже знаю ))
Re: Код pascal -> ассемблер...
Добавлено: 08 окт 2009, 11:15
somewhere
ну вот типа этого получается
Код: Выделить всё
.model tiny
.286
.code
jmp @start
;===============================================
;Input : SI - Points to null-terminated string
;Output : AX - Result number
;
Roman2Int proc
push bx
push di
xor ax, ax
@next_seq:
mov bx, [si]
or bl, bl
jz @exit
or bh, bh
jz @check_low
lea di, RomanTableH + 5*4
@Checkhigh_loop: ; -------- Checks for 2-char combination
cmp bx, [di]
jnz @checkhigh_next
add ax, [di+2]
add si, 2
jmp @next_seq
@checkhigh_next:
sub di, 4
cmp di, offset RomanTableH
jnc @checkhigh_loop
@check_low: ; -------- Checks for single char
lea di, RomanTableL + 6*3
@Checklow_loop:
cmp bl, [di]
jnz @checklow_next
add ax, [di+1]
inc si
jmp @next_seq
@checklow_next:
sub di, 3
cmp di, offset RomanTableL
jnc @checklow_loop
xor ax, ax
@exit:
pop di
pop bx
ret
RomanTableH db 'IV', 4, 0, 'IX', 9, 0, 'XL', 40, 0, 'XC', 90, 0, 'CD', 90h, 1, 'CM', 84h, 3
RomanTableL db 'I', 1, 0,'V', 5, 0,'X', 10, 0,'L', 50, 0,'C', 100, 0,'D', 0F4h, 1,'M', 0E8h, 3
Roman2Int endp
;================= MAIN ================
include wnum.asm
teststr db 'XIV',0
@start:
push cs
pop ds
mov si, offset teststr
call Roman2Int
call _write_number
mov ax, 4C00h
int 21h
end
Re: Код pascal -> ассемблер...
Добавлено: 09 окт 2009, 21:29
BBB
somewhere, спасибо, очень интересно было скомпилить, но не получилось

Отсутсвует wnum.asm. А если его закомментарить, то
Undefined symbol: _WRITE_NUMBER
UPD.
Нашел подходящую процедуру здесь:
http://forum.developing.ru/showthread.p ... t=wnum.asm
Только она там так и называлась - wnum.
Ну и еще, чтобы мой TASM сделал com-ик, пришлось вставить ORG 100H и метку к самому последнему end
В общем, получилось в итоге.
Только, как я понял, у тебя другой алгоритм, нежели Dr_Grizzly на ПАскале приводил.
Re: Код pascal -> ассемблер...
Добавлено: 12 окт 2009, 15:10
somewhere
Я как бы и сам не компилил, просто написал в окне быстрого ответа. На самом деле я уже забыл название функции в wnum.asm и мне казалось что зовется она _write_number, и в любом случае это лишь пример, здесь понятно что идет вывод содержимого в AX.
Алгоритм на самом деле немного другой, но принцип тот же - поиск последовательности, сначала из 2 символов, затем из 1 символа. Если какая то последовательность не найдется, функция вернет 0. Интересно заметить, что при использовании команд процессоров 486+ этот код сократится почти в два раза до нескольких строк.