2016-09-19 3 views
1

Я хотел бы добавить следующие цифры: 40, 90, 50 и 155, и я получаю в общей сложности 355.Ассамблеи предел бит памяти в арифметике

Я хотел поэкспериментировать и проверить ли регистр AL будет иметь бит (2^8) - 1, и когда я скомпилировал код и выполнил код, я получаю десятичное число 1376331855. Как это произошло?

Кроме того, я думал, что 355 больше 255, и в результате должно отображаться исключение переполнения.

Я понимаю, что если я использую MOVZX, я смогу провести вычисление в верхнем регистре AX.

Кроме того, я очень смущен различием между AL и AH. Есть ли разница в распределении памяти для AL и AH?

TITLE Adding    
INCLUDE Irvine32.inc 

.code 
main PROC 

    mov al,0h    ; 
    add al,28h   ; 40 

    add al,5Ah   ; 90 
    add al,32h   ;50 
    add al,9Bh   ;155 
          ; total is 355 
    call DumpRegs 
    call writedec 

exit 
main ENDP 
END main 
+0

Замените 'mov al, 0h' на' mov ax, 0h' или 'mov eax, 0h'. Я думаю, что библиотека Irvine использует EAX. –

+0

Я понимаю, почему вы это сделаете, но мне интересно узнать значение, полученное в результате использования регистра AL. Почему это значение, а не ошибка переполнения? Спасибо. –

+0

Возможно, что переполнение происходит, но вы не проверяете его. –

ответ

2

Как я понимаю, DumpRegs дает вам выход EAX. Когда я конвертирую свой ответ в HEX, я получаю 5209284F, а 4F - в AL. 4F HEX - 79 Десятичный, что составляет 335 - 256.Регистр AL содержит только 8 бит, поэтому 256 - это максимальное целое число без знака, которое оно может удерживать.

Очистить EAX до того, как вы начнете, и результаты могут иметь больше смысла.

+1

Да, именно то, что я ожидал и сказал в своем ответе. Но +1 для показа OP, что младший байт действительно удерживал ожидаемое значение. –

+2

255 - максимум. Он может содержать 256 значений, но поскольку 0 также является значением, 255 является самым высоким. –

3

Кроме того, я очень путать с разницей между AL и AH. Есть ли разница в распределении памяти для AL и AH?

Нет, нет никакой памяти. Они оба байтовые регистры в EAX.

  • AX является 16 младшими битами EAX
  • AH и AL являются высокими и низкими половинками AX

Смотри также this ascii-art diagram. Или в C:

union eax { 
    uint32_t EAX;    // regs aren't really signed or unsigned, but they have well-defined wraparound semantics like C unsigned (and unlike C signed). 
    uint16_t AX; 
    struct { uint8_t AL, AH; }; // anonymous struct, in little-endian order (AL is the low byte). 
}; 

Запись любого члена отражаются в значениях других членов, но не нулевой остаток регистра. (Footnote1)


Ваша печать функция печатает все из EAX, но вы никогда не обнуляется высокие байт EAX перед печатью. При входе в main вам необходимо предположить, что все байты EAX являются случайным мусором.

main PROC 

    xor eax, eax  ; zero eax 
    ; mov al,0h  ; instead of just zeroing al and leaving garbage in the upper 24 bits 
    add al,28h   ; then play around with the low byte if you want 
    ... 
    add al,9Bh   ; AL wraps around, but no carry happens into the rest of EAX. 
    ; If you want that, use a wider register: 
    ; add eax, 9Bh 

    call writedec   ; prints eax as a signed integer 

я подумал 355 больше, чем 255, и в результате должно отображать исключение переполнения.

Целочисленное переполнение устанавливает флаги, которые вы можете проверить позже. См. Understanding Carry vs. Overflow conditions/flags

Он не вызывает ошибок/исключений. (Кроме деления)


(1): Строгие ISO C90 и ISO C++, на самом деле не позволяют чтение члена профсоюза, который не был последним написал (неопределенное поведение). ISO C99, (and GNU C++ as an extension) do guarantee type-punning with unions works as expected.

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