【问题标题】:Assembly Homework Assignment装配作业
【发布时间】:2015-06-17 07:14:56
【问题描述】:

问题:
编写一个程序,通过将每个明文字节旋转一个变化来执行简单加密 不同方向的位置数。例如,在下面的数组中表示 加密密钥,负值表示向左旋转,正值表示 向右旋转。每个位置的整数表示旋转的幅度: 关键字节 -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 2. 我是否使用 add esi, TYPE 键行正确地递增到下一个数组索引? 3. 我理解这个问题吗?如果数组中的数字为负数,我需要将我的消息“Hello”向左旋转,如果数组中的数字为正数,则向右旋转。

任何帮助都很好,在此先感谢。

【问题讨论】:

    标签: arrays assembly x86 masm irvine32


    【解决方案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 位)。我会让你弄清楚如何解决这个问题。

    【讨论】:

    • 从我正在阅读的内容来看,ROL/ROR 指令可以与 CL 寄存器或立即数一起使用。如果需要将 ecx 用作循环计数器并且 CL 是唯一可以使用的寄存器,那么我对如何解决这个问题感到困惑。拜托,我不是在寻找直截了当的答案,而是对答案的更多提示或指导
    • @BryanHordes 您可以找到与使用ecx 不同的控制循环的方法,或者,您可以将ecx 停放在未使用的寄存器中,或者,您可以使用两条指令push ecx ... pop ecx涉及cl
    • @BryanHordes 我忽略了其他答案所说的内容。你应该使用cmp [esi], bl 而不是cmp [esi], ebx,因为esi 指向一个字节数组。
    【解决方案2】:

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

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

    @WeatherVan 指出您犯了其他错误。

    我想补充一点,由于两个补码的工作方式和旋转的对称性,您不需要进行任何跳跃。请记住:跳转是昂贵的算术不是。
    如果您取关键字节的低 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
    

    【讨论】:

      猜你喜欢
      • 2016-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多