程序集 8086 - x86 中的减法
Assembly 8086 - Subtracting in x86
我正在开发一个使用 Vigenère 密码加密/解密数据的程序。除了解密部分,一切都很好。
加密和计算密钥背后的逻辑是:
输入:“qwerty”
密钥:“asd”=计算出的密钥是“asdasd”
密码:“catdxn”
为了加密,我使用以下算法:
结果[i] = (INPUT[i]+key[i]) % 26
结果[i] += 3dH ;转换为 asci 数字
密码[i] += 结果[i]
问题出在解密:
解密算法应该是
结果[i] = (INPUT[i] - KEY[i]) % 26
IN CASE INPUT[i] - KEY[i] = NEGATIVE NUMBER = add 26 所以公式变为
结果[i] = (输入[i] - 键[i] + 26) % 26
结果[i] += 3dH
密码[i] += 结果[i] ;得到结果 String
预期的结果应该是“qwerty”,但我得到的是“usgtrm”。
所以按照上述算法,我有以下代码:
;inputKey = KEY,
;inputWORD = Input,
;cipherText = Result
;inputWORDLENGTH = length of input = CX
XOR DI,DI
vigDECLOOP:
cmp di,cx
JNB DONELOOPDEC
PUSH CX
mov si, offset inputWORD
ADD SI,DI
XOR DX,DX
MOV DL, DS:[SI] ; DL = INPUT[I]
xor SI,SI
MOV SI, OFFSET inputKEY
ADD SI, DI
XOR CX,CX
MOV CL, DS:[SI] ; CL = KEY[I]
SUB DL, CL
; ========
; Here in case is negative number I somehow need to add 26 to DL (result of DIV )
; IT 2: 61- 73 = EE in DL and should be -18, I know is something about the signed bit
; but I dont know what to read and where about this.
; ========
mov ax, cx ; Store in AX the result of subtracting
mov bx, 26 ; add in bx 26
div bx ; To obtain the reminder from % 26
; ========
; ========
add dl, 3Dh ; add 3dH to DL(reminder of DIV) to get the asci
xor si,si
mov si, offset cipherText
add si,di
xor dh,dh
add dl, DS:[si]
mov DS:[si],dl
INC DI
POP CX
jmp vigDECLOOP
DONELOOPDEC:
RET
问题出在减法上,我对这个问题一窍不通。
让我们说“catdxn”这个词。 63, 61, 74, 64, 78, 6E
和钥匙 'asdasd' 61, 73, 64, 61, 73, 64
在第 2 次迭代中,我们有 61 - 73 ( SUB DL, CL ) = 结果是 FFFF FFFF FFFF FFEE 或 - 18。
发生这种情况时,我需要将 26 添加到结果中,但我无法理解:
结果 SUB DL, CL STORES IN DL = EE 这是十进制的 238,我如何添加 26 十进制或 (1A Hex)
到一个正数...它应该是'61h - 73h = -18d + 26d 或 1Ah = 8'。可能真的错了。
The problem is at decrypt
没有。连加密都错了!正如 Jester 指出的那样,您正在使用 ASCII 代码,您应该使用字母表中字母的偏移量 [0,25]。
这是原始的Vigenère编码,subtracting/adding97转from/to小写字母:
CIPHER[i] = ((INPUT[i]-97 + KEY[i]-97) % 26) + 97
INPUT : "qwerty"
KEY : "asdasd"
CIPHER : "qohrlb"
The decrypt algorithm should be
RESULT[i] = (INPUT[i] - KEY[i]) % 26
怎么连INPUT都能解密呢?这就是解密试图找出的!
您当前代码中的一些错误包括:
- 你在
DL
中有减法的结果,你想将其除以 26,但你却将 CX
除以 26
- 你使用了字大小的除法,但忘记预先归零
DX
接下来使用字节大小除法更正了以下几个错误:
sub dl, cl
mov ax, dx ; Store in AX the result of subtracting
mov bl, 26
div bl ; To obtain the reminder from % 26
add ah, 3Dh ; add 3Dh to AH (remainder of DIV) to get the ascii
mov si, offset cipherText
add si, di
add [si], ah
为什么您认为添加 3Dh(十进制为 61)会产生 ASCII?
您当前的加密方式是这样的:
113 119 101 114 116 121 INPUT[] : "qwerty"
97 115 100 97 115 100 KEY[] : "asdasd"
--- --- --- --- --- ---
210 234 201 211 231 221 INPUT[]+KEY[]
2 0 19 3 23 13 (INPUT[]+KEY[]) % 26
cipher 63 61 80 64 84 74 (INPUT[]+KEY[]) % 26 + 3Dh
? = P @ T J CIPHER[] : "catdxn" ???
我不知道你从哪里得到你的 CIPHER。难道你将数字 63、61 和 64 解释为十六进制?这些确实代表“c”、“a”和“d”。
以及关于减法本身的问题。这完全取决于您如何查看编码数字。如果 DL
包含位模式 11101110b (EEh) 并且您以 无符号方式查看它 ,则它代表 238,但如果您以 有符号方式查看它way,则代表-18.
只需将其视为带符号的数字并添加所需的 26。您最终会得到一个 [0,25] 范围内的数字。
sub dl, cl ; DH = 0
jns IsPositive
add dl, 26
IsPositive:
mov ax, dx ; Store in AX the result of subtracting
我正在开发一个使用 Vigenère 密码加密/解密数据的程序。除了解密部分,一切都很好。
加密和计算密钥背后的逻辑是:
输入:“qwerty”
密钥:“asd”=计算出的密钥是“asdasd”
密码:“catdxn”
为了加密,我使用以下算法:
结果[i] = (INPUT[i]+key[i]) % 26
结果[i] += 3dH ;转换为 asci 数字
密码[i] += 结果[i] 问题出在解密:
解密算法应该是
结果[i] = (INPUT[i] - KEY[i]) % 26
IN CASE INPUT[i] - KEY[i] = NEGATIVE NUMBER = add 26 所以公式变为
结果[i] = (输入[i] - 键[i] + 26) % 26
结果[i] += 3dH
密码[i] += 结果[i] ;得到结果 String
预期的结果应该是“qwerty”,但我得到的是“usgtrm”。
所以按照上述算法,我有以下代码:
;inputKey = KEY,
;inputWORD = Input,
;cipherText = Result
;inputWORDLENGTH = length of input = CX
XOR DI,DI
vigDECLOOP:
cmp di,cx
JNB DONELOOPDEC
PUSH CX
mov si, offset inputWORD
ADD SI,DI
XOR DX,DX
MOV DL, DS:[SI] ; DL = INPUT[I]
xor SI,SI
MOV SI, OFFSET inputKEY
ADD SI, DI
XOR CX,CX
MOV CL, DS:[SI] ; CL = KEY[I]
SUB DL, CL
; ========
; Here in case is negative number I somehow need to add 26 to DL (result of DIV )
; IT 2: 61- 73 = EE in DL and should be -18, I know is something about the signed bit
; but I dont know what to read and where about this.
; ========
mov ax, cx ; Store in AX the result of subtracting
mov bx, 26 ; add in bx 26
div bx ; To obtain the reminder from % 26
; ========
; ========
add dl, 3Dh ; add 3dH to DL(reminder of DIV) to get the asci
xor si,si
mov si, offset cipherText
add si,di
xor dh,dh
add dl, DS:[si]
mov DS:[si],dl
INC DI
POP CX
jmp vigDECLOOP
DONELOOPDEC:
RET
问题出在减法上,我对这个问题一窍不通。 让我们说“catdxn”这个词。 63, 61, 74, 64, 78, 6E 和钥匙 'asdasd' 61, 73, 64, 61, 73, 64 在第 2 次迭代中,我们有 61 - 73 ( SUB DL, CL ) = 结果是 FFFF FFFF FFFF FFEE 或 - 18。 发生这种情况时,我需要将 26 添加到结果中,但我无法理解: 结果 SUB DL, CL STORES IN DL = EE 这是十进制的 238,我如何添加 26 十进制或 (1A Hex) 到一个正数...它应该是'61h - 73h = -18d + 26d 或 1Ah = 8'。可能真的错了。
The problem is at decrypt
没有。连加密都错了!正如 Jester 指出的那样,您正在使用 ASCII 代码,您应该使用字母表中字母的偏移量 [0,25]。
这是原始的Vigenère编码,subtracting/adding97转from/to小写字母:
CIPHER[i] = ((INPUT[i]-97 + KEY[i]-97) % 26) + 97
INPUT : "qwerty"
KEY : "asdasd"
CIPHER : "qohrlb"
The decrypt algorithm should be
RESULT[i] = (INPUT[i] - KEY[i]) % 26
怎么连INPUT都能解密呢?这就是解密试图找出的!
您当前代码中的一些错误包括:
- 你在
DL
中有减法的结果,你想将其除以 26,但你却将CX
除以 26 - 你使用了字大小的除法,但忘记预先归零
DX
接下来使用字节大小除法更正了以下几个错误:
sub dl, cl
mov ax, dx ; Store in AX the result of subtracting
mov bl, 26
div bl ; To obtain the reminder from % 26
add ah, 3Dh ; add 3Dh to AH (remainder of DIV) to get the ascii
mov si, offset cipherText
add si, di
add [si], ah
为什么您认为添加 3Dh(十进制为 61)会产生 ASCII?
您当前的加密方式是这样的:
113 119 101 114 116 121 INPUT[] : "qwerty"
97 115 100 97 115 100 KEY[] : "asdasd"
--- --- --- --- --- ---
210 234 201 211 231 221 INPUT[]+KEY[]
2 0 19 3 23 13 (INPUT[]+KEY[]) % 26
cipher 63 61 80 64 84 74 (INPUT[]+KEY[]) % 26 + 3Dh
? = P @ T J CIPHER[] : "catdxn" ???
我不知道你从哪里得到你的 CIPHER。难道你将数字 63、61 和 64 解释为十六进制?这些确实代表“c”、“a”和“d”。
以及关于减法本身的问题。这完全取决于您如何查看编码数字。如果 DL
包含位模式 11101110b (EEh) 并且您以 无符号方式查看它 ,则它代表 238,但如果您以 有符号方式查看它way,则代表-18.
只需将其视为带符号的数字并添加所需的 26。您最终会得到一个 [0,25] 范围内的数字。
sub dl, cl ; DH = 0
jns IsPositive
add dl, 26
IsPositive:
mov ax, dx ; Store in AX the result of subtracting