2013-03-23 4 views
0

Я пытаюсь понять сборку. Сегодняшняя тема: «Сохранение и приращением Int переменных и номера печати» :)Хранение и увеличение целых переменных в сборке MASM x86

Так вот мой код

dane segment 
    count  db  0 
dane ends 

code segment 
start: 
    inc  byte ptr ds:[count] 
    inc  byte ptr ds:[count] 
    inc  byte ptr ds:[count] 

    mov  dl,ds:[count] 
    mov  ah,2 
    int  21h 

    mov  ah,4ch 
    int  21h 
code ends 
end start 

Когда я скомпилировать и запустить, я получил эту ошибку:

enter image description here

Это происходит только тогда, когда count увеличивается больше одного раза. Что я делаю?

Может кто-нибудь объяснить, почему я не могу просто написать:

inc  count 

Кроме того, почему я должен положить byte ptr когда увеличивающиеся значения, но если я скопировать его в dl реестр?

+0

я не знаю об этом собрании, но вы уверены, что не увеличивает указатель вместо значения в регистрах? это сообщение об ошибке кажется повреждением кучи. – Jack

ответ

1

Edit: переписал и добавил текст, добавил код (работает в MASM 6.11):

В x86 assembbly необходимо указать размер операнда памяти для инструкций, в которых были бы неоднозначность иначе. Вы должны сообщить ассемблеру размер операнда с byte ptr, word ptr и т. Д. По этой причине inc byte ptr ds:[count] нуждается в byte ptr. inc word ptr ds:[count - другая инструкция.

mov dl,ds:[count] не нужен byte ptr, потому что dl является 8-разрядным регистром, и поэтому размер операнда памяти всегда один и тот же, байт (8 бит).

Для печати символов вам необходимо сначала преобразовать число в строку (или один символ для чисел меньше 10). В противном случае вы печатаете управление символом ETX (см ASCII table), который имеет ASCII-код 3. Для чисел меньше 10, печать в десятичном тривиальна, просто добавьте «0» (30h), как это:

 
mov  dl,ds:[count] 
add  dl,'0'  ; add dl,30h 

Печати в decimal в x86-сборке задается довольно часто, см., например, Is this code correct (Number plus number, then print the result), чтобы получить эту идею.

Редактировать: В файлах EXE также должен быть сегмент стека.

Файлы DOS EXE должны иметь сегмент стека. Сборка с MASM 6.11 не дает никаких предупреждений или ошибок, в основном с dosexe.asm (замените doctxe.asm на имя файла кода сборки).

Но связь с ML (ml dosexe.obj) дает следующее предупреждение:

 
LINK : warning L4021: no stack segment 

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

 
.model small 
.stack 4096 

Была также проблема с определением сегмента данных, я также исправил это.

Весь фиксированный код сборки может быть что-то вроде этого (работает в MASM 6.11):

 
.model small 
.stack 4096 

.data 
     count  db 0 

.code 
start: 
     mov  ax,seg count 
     mov  ds,ax 

     inc  byte ptr ds:[count] 
     inc  byte ptr ds:[count] 
     inc  byte ptr ds:[count] 

; this code does the printing in decimal without needing to reverse 
; the string, by dividing the divisor. 100/10 = 10 

     mov  bl,100  ; original divisor. 

     mov  al,ds:[count] 

print_loop: 
     xor  ah,ah ; clear top 8 bits of the dividend (in ax). 
     div  bl ; divide ax by bl. quotient in al, remainder in ah. 

     mov  dl,al  ; the value to be printed with ah = 2, int 21h 

     mov  al,ah  ; remainder gets divided in the next loop. 
     test dl,dl  ; check if number is zero 
     jz  not_print ; don't print leading zeros. 

     add  dl,'0' ; convert to ASCII numeric characters range. 
          ; '0' = 0x30 = 48 
     push ax 
     mov  ah,2 
     int  21h  ; print the value, according to Ralf Brown's 
     pop  ax  ; interrupt list returns al. 

not_print: 
     push ax 
     mov  al,bl 
     xor  ah,ah 
     mov  bl,10  ; divide the divisor by 10. 
     div  bl 
     mov  bl,al  ; the new divisor. 
     pop  ax 
     test bl,bl 
     jnz  print_loop 

     mov  ah,4ch 
     int  21h 
end start 
+0

Когда я пишу «dl, ds: [count]», то же самое печатается все время - независимо от того, что я положил в счет:/Не должно быть просто «mov dl, рассчитывать "? Я вижу это в учебниках, но я получаю ошибку A02074, когда я это делаю – msmialko

+0

@Moriquendi Какой ассемблер вы используете? Вам нужно определить сегмент данных, но я думаю, что синтаксис для этого зависит от используемого ассемблера. – nrz

+0

Мне жаль, что я не знал, что: P Я загрузил компилятор MASM с сайта моего профессора, установил 32-битную Windows XP и начал играть с образцами кода. Как я могу проверить это? Как может выглядеть другой синтаксис? – msmialko

0

[цитата] мов дл, DS: [число] не требуется байт PTR, потому что дл является 8 -битный регистр и, следовательно, размер операнда памяти всегда один и тот же, байт (8 бит). [/ quote]

И дополнительно эта операция не требует префикса переопределения сегмента, поскольку DS является сегментом по умолчанию эта операция. => Мов дл, [число]

Изменить:

Определяет программный сегмент под названием имя, имеющий сегмент атрибутов

http://msdn.microsoft.com/de-de/library/d06y3478%28v=vs.80%29.aspx

name SEGMENT [[READONLY]] [[align]] [[combine]] [[use]] [[characteristics]] ALIAS(string) [['class']] 
    statements 
    name ENDS 

Пример использования имен сегментов:

CODE SEGMENT use16 'CODE' 
assume cs:CODE,ds:DATEN,ss:STAPEL 
org 100h 
START: 
mov ax, DATEN 
mov ds, ax 

; your instructions 

CODE ends 

DATEN SEGMENT use32 'DATA' 
org 0 
VALUE DD ? 
DATEN ends 

STAPEL SEGMENT use16 STACK 'STACK' 
    DB 10h dup (0) 
STAPEL ends 

end 

Как использовать сегменты и директивы:

http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH08/CH08-3.html

...

Для связать 16 битное приложение с использованием MASM 6 нам нужен другой компоновщик.

ftp://ftp.microsoft.com/softlib/mslfiles/lnk563.exe

Dirk

 Смежные вопросы

  • Нет связанных вопросов^_^