装配家庭作业

时间:2015-06-17 07:14:57

标签: arrays assembly x86 masm irvine32

问题:
编写一个程序,通过将每个明文字节旋转变化来执行简单加密 不同方向的位置数量。例如,在以下表示的数组中 加密密钥,负值表示向左旋转,正值表示 向右旋转。每个位置的整数表示旋转的大小: 键BYTE -2,4,1,0,-3,5,2,-4,-4,6

代码:

Include Irvine32.inc

.data
msg BYTE "Hello", 0
key BYTE -2, 4, 1, 0, -3, 5, 2, -4, -4, 6

.code
main proc
mov ecx, LENGTHOF key   ;Loop Counter
mov edx, OFFSET msg     ;EDX Holds msg and will Display it
mov esi, OFFSET key     ;Point to first array element
mov ebx, 0              ;CMP number


top:
cmp [esi], ebx  ;if esi < ebx
jl ShiftLeft    ;jump to shift left

cmp [esi], ebx  ;if esi > ebx
jg ShiftRight   ;jump to shift right

cmp [esi], ebx
je NoShift

ShiftLeft:
mov cl, [esi]
SHL edx, cl
add esi, TYPE key
loop top

ShiftRight:
mov cl, [esi]
SHR edx, cl
add esi, TYPE key
loop top

NoShift:
add esi, TYPE key
loop top


call WriteString


invoke ExitProcess,0
main endp
end main

所以我遇到了一些问题。
1. cmp陈述正在逆转。所以第一个cmp应该是cmping -2和0. -2&lt; 0,所以它应该是跳跃并去Shiftleft。然而,它正在做相反的事情并且变得彻底。
2.我是否使用add esi,TYPE键线正确地增加到下一个数组索引? 我能理解这个问题吗?我需要旋转我的msg,“Hello”,如果数组中的数字为负数,则为左数,如果是数字,则向左旋转,如果数组中数字为正,则向右旋转。

任何帮助都很棒,并提前感谢。

2 个答案:

答案 0 :(得分:1)

在比较中

cmp [esi], ebx

这不会将[esi]ebx进行比较。它将ebx[esi]进行比较,这就是您认为分支决策不正确的原因。作为技术要点,您不需要测试所有三个条件,因为最后一个条件必须为真。

cmp [esi], ebx
je NoShift
jl ShiftRight   ;else fall thru to ShiftLeft

您正在使用

将指针正确移动到下一个数组位置
add esi, TYPE key

但您忘记增加消息指针edx

我认为你会通过旋转字节来编码字符,而不是移动字符,而你错误地旋转指针而不是目标

mov cl, [esi]
rol BYTE PTR [edx], cl    

还有另一个问题 - 您使用cx进行循环控制,但是您使用位移计数器覆盖clcx的l.s. 8位)。我会告诉你如何解决这个问题。

答案 1 :(得分:0)

我没有运行代码,所以分析可能是错误的。

cmp [esi], ebx 比较 [esi]当然是ebx(它只是一个[esi] -ebx)。这里的错误是您正在比较DWORD而不是字节。根据经验,始终指定内存操作数大小:cmp BYTE PTR [esi], bl这样汇编程序可以告诉您是否出错。

@WatherVan指出你犯了其他错误。

我想补充说,由于两个补码的工作方式和旋转的对称性,你不需要做任何跳跃。记住:跳是昂贵的算术不是。
如果您取得关键字节的低3位(因为您正在旋转8位数据和2 ^ 3 = 8),您可以 始终 向右旋转。左边的2的旋转是右边的6的旋转,6是3比特中的2的两个补码。

我还认为您需要在邮件上重复密钥,即如果邮件的长度超过您从一开始就需要重新加载密钥的密钥。

这是NASM中的一个示例程序,可用于更好地理解我的建议

BITS 32

GLOBAL _main

SECTION .data

 msg    db  "Hello ",0
 key    db  -2, 4, 1, 0, -3, 5, 2, -4, -4, 6

SECTION .text

_main:
 mov esi, msg

.load_key:
 mov ebx, 10        ;LENGTHOF key
 mov edi, key

.loop:
 mov cl, BYTE [edi] ;Key
 lodsb          ;Char of message
 test al, al        ;End of string?
 jz .end

 and cl, 07h        ;We are working with 8 bit numbers, 3bits of operand are enough
 ror al, cl     ;Rotate
 mov BYTE [esi-01h], al

 inc edi        ;Next char
 dec ebx        ;Key left       
 jnz .loop
jmp .load_key



.end:
 ret