所以我试图通过奇偶校验来分隔一个八位字节,我不太明白条件跳转是如何工作的(我单独尝试它并且我不明白它是如何工作的)
以下是我提出的建议:
bits 32
global start
extern exit,printf
import exit msvcrt.dll
import printf msvcrt.dll
segment data use32 class=data
s db '1', '2', '3', '4','5','7','8','9' ; declararea sirului initial s
l equ $-s ; stabilirea lungimea sirului initial l
d1 times l db 0
d2 times 1 db 0
format db "%s", 0
segment code use32 class=code
start:
mov ecx, l
mov esi, 0
jecxz Sfarsit
Repeta:
;loop so it gets all the elements from s
mov al, [s+esi]
mov bl,al
sub bl,'0'
cmp bl,2; if is even adds it to d1
JP et2
mov [d1+esi], al
inc esi
et2:
mov bl,al
sub bl,'0'
cmp bl,2; if is odd adds it to d2
JP et1
mov [d2+esi], al
inc esi
et1:
loop Repeta
Sfarsit: ;terminarea programului
;Daca dorim si afisarea sirului d, avem urmatoarele:
push dword d1 ; punem parametrii pe stiva de la dreapta la stanga
push dword format
call [printf] ;apelam functia printf
add esp, 4 * 2 ; eliberam parametrii de pe stiva
; exit(0)
push dword d2 ; punem parametrii pe stiva de la dreapta la stanga
push dword format
call [printf] ;apelam functia printf
add esp, 4 * 2 ; eliberam parametrii de pe stiva
; exit(0)
push dword 0 ; push the parameter for exit onto the stack
call [exit] ; call exit to terminate the program
我认为问题是JP
,但我并不完全确定。
答案 0 :(得分:2)
cmp bl,2; if is even adds it to d1
JP et2
在这种情况下, cmp
执行temp = bl - 2
并抛弃结果,但会阻止标记受影响(与sub bl,2
相同的方式会影响它们)。
并且jp
是"跳转奇偶校验",这意味着它将在PF = 1时跳转,它还具有别名jpe
或"甚至"
但这是关于低8位结果的位奇偶校验,即它计算" 1"结果的低8位值,当有偶数时,设置PF = 1。由于您在算术标志设置指令(cmp
)中仅使用了8位,因此整个结果用于计算PF,但如果您执行cmp ebx,2
,则在PF中会产生相同的结果,因为只有8位结果用于计数。
在您的情况下处理的值(二进制):
bl temp (low 8b) PF
0001 (1) 11111111 (-1) 1 (8 mod 2 = 0)
0010 (2) 00000000 (0) 1 (0 mod 2 = 0)
0011 (3) 00000001 (1) 0 (1 mod 2 = 1)
0100 (4) 00000010 (2) 0 (1 mod 2 = 1)
0101 (5) 00000011 (3) 1 (2 mod 2 = 0)
0111 (7) 00000101 (5) 1 (2 mod 2 = 0)
1000 (8) 00000110 (6) 1 (2 mod 2 = 0)
1001 (9) 00000111 (7) 0 (3 mod 2 = 1)
所以bl
值1,2,5,7,8将会jp
跳跃。
如果你想测试bl
,如果值是偶数(bl mod 2 = 0
),那么你需要:
test bl,1 ; mask-out all bit except the lowest one
jz even_value ; when lowest bit is zero, value is even
test
指令执行temp = bl AND 00000001
,抛出结果(temp),只保留标志。二进制值是偶数,当它们的最低位(位)为零时,因为它具有值2 0 = 1,所以这是使奇数值成为可能的值。当您按原样对00000001屏蔽原始值时,只保留最低位,因此jz
"跳零和#34;当最低位为零时将发生 - >价值是均匀的。
您可能会遇到更多问题:
d1 times l db 0
d2 times 1 db 0 ; probably "times l db 0" meant?
你想在奇怪的时候将价值分成d1 / d2
吗?
但是你使用相同的索引esi
,所以如果你要修改你的测试,你的"存储价值进入"逻辑,您将值分成两个数组:
d1: '1', 0, '3', 0, '5', '7', 0, '9'
d2: 0, '2', 0, '4', 0, 0, '8', 0
您当前的代码只会存储设置PF = 0的值,但会存储到两个数组中,因为两个分支都有相同的计算。
要获得如上所述的数组(奇数/偶数值,在原始索引上),您可以这样做:
mov edi,d1 ; target array ptr for odd values
mov edx,d2 ; target array ptr for even values
test al,1 ; test if al has even value
; you can test directly the ASCII digit, '0' = 0x30 = even
cmovz edi,edx ; edi = target array ptr
mov [edi+esi],al ; store AL into desired array
...而且我甚至不会检查该循环下面的代码,但我认为你应该在调试器中执行它,并在每条指令上单步执行以查看它的作用(很可能不是,你想要的是什么) /预期)。