FallenSoul
|
|
« : 06-11-2007 17:46 » |
|
1. Программа выводящая 2-4 значные числа на экран 2. МАСМ611, АМД 1.7 3. Конвертирование числа в символьный массив происходит почленными делением, разбивая на разряды и занося их в новый массив,а затем обратным считыванием производится вывод 4. Попытался как смог закомментировать свои действия, но на экране мусор. Мб что то забыл, или не правильно использовал какую то команду. Программу попросил написать преподователь, поэтому исходный код работающей проги брать не стал-пишу сам. SSEG SEGMENT STACK DB 256 DUP (?) SSEG ENDS
DATA SEGMENT NEW_A DB 6 DUP (?) ; Массив для записи результата по разрядам NUM DB 149 ; Число которое будем выводить на экран DATA ENDS
CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:SSEG START PROC FAR PUSH DS PUSH AX MOV BX,DATA MOV DS,BX CALL MAIN RET START ENDP
MAIN PROC FAR XOR AX,AX XOR BX,BX XOR CX,CX XOR DX,DX MOV CX,2 ;Цикл на 3 итерации MOV SI, OFFSET NEW_A ;В регистр SI поместили адрес массива NEW_A MOV AL,NUM ;Занесли в делимое число, которое надо вывести на экран MOV DL,10 ;Будем делить наше число на 10, тем самым разбивая на порядки M: DIV DL ;Делим. Остаток в AH, результат в AL (AH=9, AL=14)(AH=4, AL=1) MOV [SI],AH ;Поместили первый остаток как первый элемент массива _ _ _ _ _ 9 , _ _ _ _ 4 9 INC SI ;Для записи выставлен следующий элемент
CMP AL,00001010B ;Сравниваем результат с десяткой JB FINISH_DIV ;Если AL меньше десятки, то переход на завершение деления ;и помещения частного последним элементом массива LOOP M
FINISH_DIV :
MOV [SI],AL ;Записывается последняя еденица в разряд сотни _ _ _ 1 4 9
MOV CX,3 ; Цикл на 3 итерации N: MOV DL,NEW_A[SI] ;Текущий элемент массива помещается в DL OR DL,00110000B ;Добавляется признак ASCII кода MOV AH,2 ;Для вывода через прерывание 21h INT 21H DEC SI ;Для вывода выставлен предыдущий элемент (941 = 1->4->9) LOOP N RET MAIN ENDP
CODE ENDS END START
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 06-11-2007 19:26 » |
|
FallenSoul, пытаюсь разобраться (но уставшее я щас), пробую в VC++6 , вот тут мне компилятор ругается: говорит что illegal reference to 16-bit data in 'first operand' . И хочь ты тресни. А я не помню, почему тут так и вообще, если не ошибаюсь , лучше вместо MOV SI, OFFSET NEW_A ... mov [SI],AH
сделать MOV SI, 0 ... mov NEW_A[SI],AH
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #2 : 06-11-2007 19:33 » |
|
Леш, все потому, что в студии ты 32-битный код пишешь, а тут 16-битный - просто не совместимо.
FallenSoul, отладчиком пройди пошагово и посмотри, где результат не тот, что ожидался.
|
|
« Последнее редактирование: 06-11-2007 19:41 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 06-11-2007 19:37 » |
|
RXL, аа , блин, надо же esi юзать ))) В студии то есть
Делится, кстати, правильно. Значит косяк в работе с прерыванием. Это я уже не проверю...
|
|
« Последнее редактирование: 06-11-2007 19:39 от Алексей1153++ »
|
Записан
|
|
|
|
Sla
|
|
« Ответ #4 : 06-11-2007 20:05 » |
|
на вскидку а POP AH, POP DS? XOR CX,CX Лишнее, за ним MOV CX,2
MOV AH,2 можно вынести за пределы цикла N
кроме того в самой процедуре MAIN портятся регистры, кто их будет восстанавливать? а так похоже на правду
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Serg79
|
|
« Ответ #5 : 07-11-2007 11:50 » |
|
Вот пример функции которая отображает шестнадцатиразрядное число. Только используется не функция DOS (21h), а функция BIOS (10h). Если необходимо использовать именно сервисы DOS (например, чтобы работало перенаправление ввода-вывода) то замени вызов BIOS-а вызовом DOS. /* ax - число для отображения в hex */ print_hex: pushw %cx pushw %dx
movw $4,%cx /* 4 hex числа */ movw %ax,%dx /* регистр AX будет нужен для вызова int */
1: rolw $4,%dx /* получим старшие 4 разряда */ movw $0xe0f,%ax /* ah = вызов BIOS, al = маска значения */ andb %dl,%al daa /* преобразуем в ASCII hex (три инструкции) */ addb $0xf0,%al adcb $0x40,%al /* al = ASCII hex 0..9A..F */ int $0x10 /* отобразим с использованием BIOS */ loop 1b /* повторим для четырех значений */
popw %dx popw %cx ret
|
|
|
Записан
|
|
|
|
FallenSoul
|
|
« Ответ #6 : 07-11-2007 13:13 » |
|
Спасибо, но я свою дописал С помощью TD прошёлся по программе, подкорректировал некоторые моменты. Вот собственно результат. Спасибо всем кто ответил! SSEG SEGMENT STACK DB 256 DUP (?) SSEG ENDS
DATA SEGMENT NEW_A DB 6 DUP (?) ; Массив для записи результата по разрядам NUM DB 149 ; Число которое будем выводить на экран DATA ENDS
CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:SSEG START PROC FAR PUSH DS PUSH AX MOV BX,DATA MOV DS,BX CALL MAIN RET START ENDP
MAIN PROC XOR AX,AX XOR BX,BX XOR DX,DX MOV CX,2 ;Цикл на 2 итерации (0-255. 255/100<10) MOV SI, OFFSET NEW_A ;В регистр SI поместили адрес массива NEW_A MOV AL,NUM ;Занесли в делимое число, которое надо вывести на экран MOV DL,10 ;Будем делить наше число на 10, тем самым разбивая на порядки M: DIV DL ;Делим. Остаток в AH, результат в AL (AH=9, AL=14)(AH=4, AL=1) MOV [SI],AH ;Поместили первый остаток как первый элемент массива _ _ _ _ _ 9 , _ _ _ _ 4 9 INC SI ;Для записи выставлен следующий элемент
CMP AL,00001010B ;Сравниваем результат с десяткой JL FINISH_DIV ;Если AL меньше десятки, то переход на завершение деления ;и помещения частного последним элементом массива MOV AH,0 MOV DL,10 LOOP M
FINISH_DIV :
MOV AH,2 ;Для вывода через прерывание 21h MOV [SI],AL ;Записывается последняя еденица в разряд сотни _ _ _ 1 4 9
MOV CX,3 ; Цикл на 3 итерации N: MOV DL,NEW_A[SI] ;Текущий элемент массива помещается в DL OR DL,00110000B ;Добавляется признак ASCII кода CMP DL,00110000B ;Если не цифра, (<0) JL QUIT ;то на выход CMP DL,00111010B ;Если не цифра, (>9) JNL QUIT ;то на выход INT 21H DEC SI ;Для вывода выставлен предыдущий элемент (941 = 1->4->9) LOOP N QUIT: RET MAIN ENDP
CODE ENDS END START
|
|
« Последнее редактирование: 07-11-2007 13:20 от FallenSoul »
|
Записан
|
|
|
|
|