Reputation: 21
My original assignment question is this:
Write a program that uses the variables below and MOV instructions to copy the value from bigEndian to littleEndian, reversing the order of the bytes. The number's 32 - bit value is understood to be 12345678 hexadecimal.
.data bigEndian BYTE 12h, 34h, 56h, 78h littleEndian DWORD?
I think my code is right but I can't figure out why I am getting this error. Here's my code and error:
.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 started: Project: BigEndianLittleEndian, Configuration: Debug Win32 ------
1> Assembling BigEndiantoLittleEndian.asm...
1>BigEndiantoLittleEndian.asm(20): error A2008: syntax error
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations\masm.targets(50,5): error MSB3721: The command "ml.exe /c /nologo /Zi /Fo"Debug\BigEndiantoLittleEndian.obj" /W3 /errorReport:prompt /TaBigEndiantoLittleEndian.asm" exited with code 1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
How can I fix this error?
Here is updated code:
.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
The error I get
1>------ Build started: Project: BigEndianLittleEndian, Configuration: Debug Win32 ------
1> Assembling BigEndiantoLittleEndian.asm...
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets(708,9): error MSB4030: "main" is an invalid value for the "NoEntryPoint" parameter of the "Link" task. The "NoEntryPoint" parameter is of type "System.Boolean".
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Upvotes: 0
Views: 15587
Reputation: 9
I actually just had this exact same assignment, thought i would post my answer here. There IS a way to swap the bytes around by taking advantage of pointers and the OFFSET command. LittleEndian is only applied when writing bytes to memory. Which means when you run the following code, eax will hold the reversed bytes of bigEndian.
LittleEndian <=> BigEndian
mov ebx,OFFSET bigEndian
mov eax, [ebx]
This assignment however, restricted us to only using the mov operator. In my case, the OFFSET operators are not allowed either. Literally all we could use was mov. In light of this, you will need to swap the bytes around manually, and since you cannot move data from memory to memory, we are forced to use an 8-bit register as a buffer to temporarily hold the data.
You can access each byte of bigEndian individually by using offsets bigEndian+0 -> bigEndian+3, but considering we declared littleEndian after bigEndian, memory was allocated for littleEndian just after bigEndian. Which means if we move offsets bigEndian+4 -> bigEndian+7 we can directly access littleEndian using small 8-bit increments. I took advantage of this and used it in my code.
EDIT: Here is the final result
.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
Upvotes: 0
Reputation: 187
I came up with what seems like a better way to do solve the problem. It still sticks to the restraint of only using MOV
instructions, but it doesn't destroy the array's original value.
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
Upvotes: 1
Reputation: 187
I just finished this in my Assembly course. Here is what I painstakingly came up with. I am almost certain that there is a better, and more correct way to do it, but this was the only way that I could figure it out. Haven't turned it in for a grade yet, so I don't know how well it well hold up in that aspect. I suspect it will be fine. It does what the problem requested, within the constraints set.
; 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
Upvotes: 1
Reputation: 812
You should actually swap bytes in eax
before writing it back to memory:
mov eax,DWORD PTR bigEndian
bswap eax
mov littleEndian,eax
By using exclusively mov
instructions it could be like this:
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
Upvotes: 5