2015-03-27 9 views
3

Я пытаюсь дать одноразрядное число и знать, является ли четность четным или даже, например, дать 9 и напечатать, что является нечетным числом.Соотношение числа (сборка 8086)

Это то, что у меня есть:

assume cs:cseg,ds:dseg,ss:sseg 
    cseg segment 
    start: 
    mov ax, dseg 
    mov ds, ax 

    mov ah, 01h ; Here, im adding a number 
    int 21h 



    jp even 
    jnp odd 

    even: 
    mov ah,09 
    lea dx,par 
    int 21h 
    jmp exit 
    odd: 
    mov ah,09 
    lea dx,odd1 
    int 21h 
    jmp salir 
    salir: 
    mov ax,4C00h 
    int 21h 

    cseg ends 

    dseg segment byte   
    even Db 'Even number$' 
    odd11 Db 'Odd number$' 
    dseg ends 

    sseg segment stack 
    db 100h dup(?) 
    sseg ends 

end start 

Спасибо! И извините за мой плохой английский.

ответ

0

Я нашел решение!

Просто добавьте «и др, 00000001» сверху JP даже

assume cs:cseg,ds:dseg,ss:sseg 
    cseg segment 
    start: 
    mov ax, dseg 
    mov ds, ax 

    mov ah, 01h ; Here, im adding a number 
    int 21h 

and al,00000001 

    jp even 
    jnp odd 

    even: 
    mov ah,09 
    lea dx,par 
    int 21h 
    jmp exit 
    odd: 
    mov ah,09 
    lea dx,odd1 
    int 21h 
    jmp salir 
    salir: 
    mov ax,4C00h 
    int 21h 

    cseg ends 

    dseg segment byte   
    even Db 'Even number$' 
    odd11 Db 'Odd number$' 
    dseg ends 

    sseg segment stack 
    db 100h dup(?) 
    sseg ends 

end start 
+0

1 - 0000_0001 нечетное число, четность нечетная. 2 - 0000_0010 четное число, четность нечетная. 3 - 0000_0011 нечетное число, четность четная. Что вы на самом деле пытаетесь сделать? –

+0

Лучше: 'test al, 1' вместо' and al, 1'. Такая же длина инструкции, но может макро-fuse с 'jcc' на современных процессорах. (Даже 'jp', хотя четность одного бита такая же, как и проверка того, является ли он нулевым, что было бы легче понять и так же быстро, хотя это и работает.) –

2

Чтобы проверить, является ли число четным или нечетным, просто сдвинуть его вправо еще и проверить флаг переноса:

mov  al, 09 
    shr  al  ; shifts all bits right 1, lowest bit to carry flag 
    jc  _odd  ; carry set - there was a bit in lowest position 
_even: 
    ; Do something with even numbers and exit 
_odd: 
    ; Do something with odd numbers and exit 

Понимание флага переноса очень полезно для целого ряда трюков кодирования. Например, «Паритет» рассчитывает на общее число битов в количестве, и мы можем использовать подобный трюк для этого:

mov ah, 09 
    xor al, al ; al = 0 
_loop: 
    shr ah  ; lower bit into carry flag 
    adc al, 0  ; Add 0 + carry flag to al 
    and ah, ah ; sets Z flag if ah is zero 
    bne _loop 
    ; al now contains the total number of bits contained in ah 
+1

минус для« просто сдвиньте его вправо один раз и проверьте флаг переноса ", который уничтожает данные, которые проверяются –

+2

Он просто хочет знать, странно это или нет, а не повторно использовать его. 1 байт инструкций и отсутствие служебных данных для доступа к памяти - это наиболее эффективный способ проверки *, если * вы не собираетесь использовать значение снова (что у него нет в его коде). – Mike

+0

@Mike: 'test al, 1' /' jnz _odd' * значительно * более эффективен, чем сдвиг. На Intel с Core2 и AMD с Bulldozer, которые могут скомпенсировать макрос в единую тестовую ветвь. 'shr al' и' test al, 1' являются 2-байтными инструкциями.Ваша петля также менее эффективна, чем могла бы быть. Первый «тест ах, ах» будет лучше, чем 'и'. Во-вторых, вы можете организовать его, чтобы вы введете на ZF, как установлено 'shr'. (например, с помощью 'adc al, 0' /' shr ah'/'jnz _loop' /' adc al, 0'. На первой итерации 'adc al, 0' является no-op, потому что' xor al, al 'очищенный CF. После выхода из цикла вы добавляете CF последнего бит. –

4

Чтобы проверить, является ли число четным или нечетным, вы проверить бит 0 это число. если бит0 установлен, то число нечетно. ничего больше. Не путайте PF (флаг четности) и условия JP/JNP. Флаг четности показывает, является ли количество бит, установленное в младшем значении байта, четным или нечетным.

Из документации:

ПФ (бит 2) флаг четности - Устанавливается, если младший байт результата содержит четное число 1 бит; очищено в противном случае.

Номер 1 - нечетное число, 00000001b PF очищается, потому что есть только один бит установлен
номер 2 - четное число, 00000010b, но PF очищается еще раз! потому что есть только один бит
Номер 3 - нечетное число, 00000011b, но набор PF! потому что вы два бита установить

+0

Как проверить бит 0? – TheLogicGuy

+0

@TheLogicGuy: 'test eax, 1' –

+0

Или лучше,' test al, 1', потому что нет 'test r32, imm8' -кодирование, поэтому короче всего читать младший байт 'eax', читая' al'. (Написание неполных регистров плохо, чтение их в порядке.) –

3

Хотя ответ Александра ЖАК в указал на недостатки в вашем коде, проверяя флаг четности, самый быстрый способ проверить четность числа в ал в не desctructive способом является:

 test al,1 
     jz even 
odd: ... 
even: ... 
-1
.MODEL SMALL 
.STACK 100H 

.DATA 
    PROMPT_1 DB 'Enter a number: $' 
    PROMPT_2 DB 0DH,0AH,'The given number in binary is: $' 
    PROMPT_3 DB 0DH,0AH,'$' 
    MSG1 DB 10,13,’Number is Odd $’ 
    MSG2 DB 10,13,’Number is Even $’ 

.CODE 
    MAIN PROC 
    MOV AX, @DATA     
    MOV DS, AX 

    LEA DX, PROMPT_1     
    MOV AH, 9 
    INT 21H 

    XOR BL, BL     
    MOV CX, 8     
    MOV AH, 1     

    @INPUT:      
     INT 21H     
     CMP AL, 0DH     
     JE @END     
     AND AL, 0FH     
     SHL BL, 4     
     OR BL, AL     
    LOOP @INPUT     

    @END:       

    MOV AL, BL     
    MOV CX, 8      

    @LOOP:      
     SHR AL, 1     
     RCL BL, 0     
    LOOP @LOOP     

    LEA DX, PROMPT_2    
    MOV AH, 9 
    INT 21H 

    MOV CX, 8      
    MOV AH, 2      

    @OUTPUT:      
     SHL BL, 1     

     JNC @ZERO     
     MOV DL, 31H    
     JMP @DISPLAY    

     @ZERO:      
     MOV DL, 30H    

     @DISPLAY:     
     INT 21H     
    LOOP @OUTPUT      



MOV AH,01H 
INT 21H 

mov ah,01h 


SAR AL,01h 
JC ODD 


LEA SI,MSG1 
CALL PRINT 

JMP TERMINATE 

ODD: 
LEA SI,MSG2 
CALL PRINT 


TERMINATE: 
MOV AH,4CH 
INT 21H 

PRINT PROC 
MOV DX,SI 
MOV AH,09H 
INT 21H 




    MOV AH, 4CH     
    INT 21H 

END MAIN 
+0

Что это делает, и почему это полезный ответ на этот вопрос? Является ли 'shr al, 1'/'rcl bl, 0' /' loop', который должен битово-обратный AL? Это не так: ['rcl'] (http://felixcloutier.com/x86/RCL:RCR:ROL:ROR.html) с количество нулей - дорогостоящее no-op и не поддерживается на 8086. 'r cl bl, 1' работает на 8086 и сделает правильный бит-обратный цикл. Во всяком случае, вам нужно всего лишь взглянуть на последнюю десятичную цифру многозначного числа, чтобы решить, странно это или нет, так что вы слишком замаскируете это (что бы это ни было ...) –