2015-11-18 9 views
1

У меня есть задание:программа Ассамблеи добавить нечетные числа с помощью условного перехода

написать ассемблерный код, чтобы добавить следующие пятнадцать нечетные числа с помощью условного перехода.

Нечетные числа: 3, 5, 7, 9, 11, 13, 15, 17, 19, 21,23,25,27,29,31

я сделать это решение. Я хочу, чтобы проверить это, что случилось в этом ...

[org 0x0100] 
mov bx, num1 
mov cx, 15 
mov ax, 0 
li: 
add ax, [bx] 
add bx, 2 
sub cx, 1 
jnz li 
mov ax, 0x4c00 
int 0x21 
num1: dw 3, 5, 7, 9, 11, 13, 15, 17, 19, 21,23,25,27,29,31 
+1

Что заставляет вас думать, есть что-то не так с ним? Мне кажется, хорошо для меня –

+0

Я использую AFD, чтобы найти ошибки ... и код не работает на этом ... регистр перегрузки типа ошибка будет написана их. –

+0

Ваш код выглядел отлично. До сих пор я никогда не использовал AFD.EXE. Я загрузил его, и я запустил ваш код в том, что использовал F1, чтобы пройти через ваш код до тех пор, пока не будет просто * до * вызова 'mov ax, 0x4c00'' int 0x21' и _AX_, содержащего '0xFF', который равен 255 десятичным. 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 + 21 + 23 + 25 + 27 + 29 + 31 = 255, так что это выглядит хорошо для меня. Где вы видите эту ошибку перегрузки по регистру? Я собрал ваш код с 'nasm -f bin testit.asm -o testit.com'. Затем я загрузил DOSBOX и загрузил его 'AFD TESTIT.COM' –

ответ

0

Это, конечно, один способ сделать это, единственное, что вам нужно быть осторожным является тот факт, что вы накапливая сумму в ax но то вы переписываете ax при выходе из программы с int 21, fn 4c.

По счастливому совпадению, эти цифры в сумме дают 255, так что будет на самом деле подходят в al, который является регистр, используемый для кода возврата с помощью этого прерывания (см Ralf Brown's excellent interrupt list). DOS будет делать

ли что-нибудь умное с ним, я не мог сказать :-)

В целях сохранения al при выходе из программы, просто сделать это вместо:

mov ah, 0x4c 
int 0x21 

Другая вещь, которую вы, возможно, захотите рассмотреть, - это распечатать элемент напрямую, а не возвращать его. Следующий код показывает, как сделать это, используя функцию из своего арсенала, способный выводить на al регистр в качестве значения базовых десять:

 org  00100h 

     mov  bx, num1 
     mov  cx, 15 
     mov  ax, 0 
li: 
     add  ax, [bx] 
     add  bx, 2 
     sub  cx, 1 
     jnz  li 

     call prt_byte 

     mov  ah, 04ch 
     int  021h 

num1: dw  3, 5, 7, 9, 11, 13, 15, 17, 19, 21,23,25,27,29,31 
eoln: db  0dh, 0ah, '$' 

prt_byte: 
     push ax 
     push bx 
     push dx 

     cmp  ax, 100 
     jl  skip_h 

     push ax 

     mov  bl, 100    ; divide ax by 100. 
     div  bl 
     mov  ah, 0 

     call prt_digit 

     mul  bl     ; remove hundreds digit. 
     mov  bx, ax 
     pop  ax 
     sub  ax, bx 

skip_h: 
     cmp  ax, 10 
     jl  skip_t 

     push ax 

     mov  bl, 10    ; divide ax by 10. 
     div  bl 
     mov  ah, 0 

     call prt_digit 

     mul  bl     ; remove tens digit. 
     mov  bx, ax 
     pop  ax 
     sub  ax, bx 

skip_t: 
     call prt_digit 

     mov  dx, offset eoln 
     mov  ah, 9 
     int  021h 

     pop  dx 
     pop  bx 
     pop  ax 
     ret 

prt_digit: 
     push ax     ; save registers. 
     push dx 

     mov  dx, ax    ; put in correct register. 
     add  dx, '0'    ; turn into digit. 
     mov  ah, 2    ; print. 
     int  021h 

     pop  dx     ; restore registers and return. 
     pop  ax 
     ret 
+0

Для 0-99 целых чисел 'div r8' на 10 дает вам 2 цифры, которые вы хотите в порядке печати (quotient = MSD в 'al', который переходит на низкий адрес в памяти = начало строки, если вы храните' ax'). Таким образом, вы можете добавить '0x3030' (' '00''), чтобы превратить это в две цифры ASCII. Или с 32-битным регистром, 'add eax, 0x0a3030', чтобы включить 3-й байт от 0 до новой строки. –