我的原始作业问题是:
编写一个程序,使用下面的变量和MOV指令将值从bigEndian复制到littleEndian,反转字节的顺序。数字的32位值被理解为12345678十六进制。
.data bigEndian BYTE 12h, 34h, 56h, 78h littleEndian DWORD?
我认为我的代码是正确的,但我无法弄清楚为什么我会收到此错误。这是我的代码和错误:
.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
.data
bigEndian BYTE 12h, 34h, 56h, 78h
littleEndian DWORD ?
.code
main PROC
mov eax, DWORD PTR bigEndian; eax = 87654321h
mov littleEndian, eax
invoke ExitProcess, 0
main ENDP
END main
1> ------ Build build:Project:BigEndianLittleEndian,配置:Debug Win32 ------
1>组装BigEndiantoLittleEndian.asm ......
1> BigEndiantoLittleEndian.asm(20):错误A2008:语法错误
1> C:\ Program Files(x86)\ MSBuild \ Microsoft.Cpp \ v4.0 \ V140 \ BuildCustomizations \ masm.targets(50,5):错误MSB3721:命令“ml.exe / c / nologo / Zi /Fo"Debug\BigEndiantoLittleEndian.obj“/ W3 / errorReport:prompt /TaBigEndiantoLittleEndian.asm”退出,代码为1。
==========构建:0成功,1失败,0最新,0跳过==========
如何解决此错误?
这是更新的代码:
.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
.data
bigEndian BYTE 12h, 34h, 56h, 78h
littleEndian DWORD ?
.code
main PROC
mov ah, byte ptr bigEndian+0
mov al, byte ptr bigEndian+1
mov word ptr littleEndian+2,ax;here I want to move my now full register into the 32bit register eax.
mov ah, byte ptr bigEndian+2
mov al, byte ptr bigEndian+3
mov word ptr littleEndian+2,ax here I want to move my now full register into the 32bit register eax which results in the order being reversed.
invoke ExitProcess, 0
main ENDP
END main
我得到的错误
1> ------ Build build:Project:BigEndianLittleEndian,Configuration:Debug Win32 ------
1>组装BigEndiantoLittleEndian.asm ......
1> C:\ Program Files(x86)\ MSBuild \ Microsoft.Cpp \ v4.0 \ V140 \ Microsoft.CppCommon.targets(708,9):错误MSB4030:“main”是“for”的无效值NoEntryPoint“链接”任务的参数。 “NoEntryPoint”参数的类型为“System.Boolean”。
==========构建:0成功,1失败,0最新,0跳过==========
答案 0 :(得分:3)
你应该在eax
之前交换字节,然后再将其写回内存:
mov eax,DWORD PTR bigEndian
bswap eax
mov littleEndian,eax
完全使用mov
指令可能是这样的:
mov al,DWORD PTR bigEndian+0
mov ah,DWORD PTR bigEndian+1
mov bl,DWORD PTR bigEndian+2
mov bh,DWORD PTR bigEndian+3
mov littleEndian+0,bh
mov littleEndian+1,bl
mov littleEndian+2,ah
mov littleEndian+3,al
答案 1 :(得分:1)
我刚刚在我的装配课程中完成了这个。这是我辛苦提出的。我几乎可以肯定,有一种更好,更正确的方法,但这是我能想出来的唯一方法。 Haven尚未将其转入等级,因此我不知道它在这方面的表现如何。我怀疑它会好的。它在约束集中执行问题请求。
; Description: Copy value from bigEndian to littleEndian, reversing order of bytes
; Assignment: A06B 4.10 Programming Exercise
; Date: 3/17/2016
INCLUDE Irvine32.inc
.data
bigEndian BYTE 12h, 34h, 56h, 78h
littleEndian DWORD ?
.code
main PROC
mov al, [bigEndian+3] ;swap 78h and 12h
mov ah, [bigEndian]
mov [bigEndian], al
mov [bigEndian+3], ah
mov al, [bigEndian+2] ;swap 56h and 34h
mov ah, [bigEndian+1]
mov [bigEndian+1], al
mov [bigEndian+2], ah
mov eax, DWORD PTR bigEndian ;move reverse ordered bytes to eax
mov littleEndian, eax ;move reverse ordered byted to littleEndian
invoke ExitProcess, 0
main ENDP
END main
答案 2 :(得分:1)
我提出了解决问题的更好方法。它仍然坚持只使用MOV
指令的约束,但它不会破坏数组的原始值。
INCLUDE Irvine32.inc
.data
bigEndian BYTE 12h, 34h, 56h, 78h
littleEndian DWORD ?
.code
main PROC
mov esi, OFFSET bigEndian
mov eax, 0
mov al, [esi+3] ;Isolate 5678h
mov ah, [esi+2]
mov ebx, 0
mov bl, [esi+1] ;Isolate 1234h
mov bh, [esi]
mov esi, OFFSET littleEndian
mov [esi], eax ;Move 5678h into lower 16bits of littleEndian
mov [esi+2], ebx ;Move 1234h into higher 16bits of littleEndian
invoke ExitProcess, 0
main ENDP
END main
答案 3 :(得分:0)
我实际上只是完成了同样的任务,我想我会在这里发布我的答案。有一种方法可以通过利用指针和OFFSET命令来交换字节。 LittleEndian仅在将字节写入内存时应用。这意味着当您运行以下代码时,eax将保留bigEndian的反转字节。
LittleEndian< =>大尾端
mov ebx,OFFSET bigEndian
mov eax, [ebx]
然而,这个赋值仅限于使用mov运算符。就我而言,也不允许使用OFFSET运算符。我们可以使用的所有内容都是mov。鉴于此,您需要手动交换字节,并且由于无法将数据从内存移动到内存,因此我们不得不使用8位寄存器作为缓冲区来临时保存数据。
您可以使用偏移bigEndian + 0 - >单独访问bigEndian的每个字节。 bigEndian + 3,但考虑到我们在bigEndian之后宣布了littleEndian,内存是在bigEndian之后为littleEndian分配的。这意味着如果我们移动偏移bigEndian + 4 - > bigEndian + 7我们可以使用小的8位增量直接访问littleEndian。我利用了这个并在我的代码中使用它。
编辑:这是最终结果
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
INCLUDE Irvine32.inc
.data
bigEndian BYTE 12h, 34h, 56h, 78h
littleEndian DWORD ?
.code
main proc
; You can swap them by taking advantage of when littleEndian is applied to variables in memory.
; Since we are limited to only mov operators, we cannot use this code. But it's nice to have for the future.
; mov ebx,OFFSET bigEndian
; mov eax, [ebx]
; Display bigEndian
mov ebx, 1 ;set to write eax al 8 hex digits using WriteHexB
mov al, bigEndian+0
call WriteHexB
mov al, bigEndian+1
call WriteHexB
mov al, bigEndian+2
call WriteHexB
mov al, bigEndian+3
call WriteHexB
call CrlF
; Since bigEndian was declared before littleEndian, bigEndian only goes as far as bigEndian+3
; However, since littleEndian was declared after, we can traverse littleEndian using bigEndian+4 -> bigEndian+7.
; Considering we cannot move data from memory to memory, we have to use an 8-bit register as a buffer.
; We will use al register.
; bigEndian = 12345678h, littleEndian = 00000000h
mov al, bigEndian+0
mov bigEndian+4, al
; bigEndian = 12345678h, littleEndian = 00000012h
mov al, bigEndian+1
mov bigEndian+5, al
; bigEndian = 12345678h, littleEndian = 00003412h
mov al, bigEndian+2
mov bigEndian+6, al
; bigEndian = 12345678h, littleEndian = 00563412h
mov al, bigEndian+3
mov bigEndian+7, al
; bigEndian = 12345678h, littleEndian = 78563412h
; Write littleEndian to eax to display on screen
mov eax, littleEndian
; Display littleEndian
call WriteHex
call CrlF
; Display 'Press [enter] to continue...'
call WaitMsg
invoke ExitProcess,0
main endp
end main