I am using visual studio for assembly coding and I am pretty new to assembly. My problem is when I assign a number to a register the value of the number is changed.
.386
.model flat, stdcall
stack 4096
ExitProcess PROTO, dwExitCode: DWORD
.data
;define your variables here
adword DWORD ?
aword WORD 7788h
.code
main PROC
mov eax,11223344h ; moved a constant into a register
mov ebx, eax ; moved ebx -> eax
mov adword, eax ; mov eax-> adword
mov ax, aword ; 7788h -> ax
mov ah, 10h
INVOKE ExitProcess, 0
main ENDP
END main
The value of Eax is not 11223344 it becomes something else.
I am in an Assembly language class in college and we are working on assignment that prints data using printf. In class we use Visual Studio Professional 2015 but on my laptop I have Visual Studio Community 2017. In class we change have to change the toolset to a 2013 version but my visual studio does not have that. Here is my code: (it worked perfectly in class but I get errors when running it on my pc):
; Author: Keenan Kaufman
; Date: 9/20/2017
.586
.MODEL FLAT, STDCALL
INCLUDELIB msvcrt.lib
EXTERN printf:NEAR
EXTERN exit:NEAR
.STACK 4096
.DATA
plain BYTE 'Hello, World!'
key BYTE 02h
cipher BYTE SIZEOF plain DUP(?)
.CODE
main PROC
sub eax, eax ; clear registers
sub ebx, ebx
sub ecx, ecx
mov ebx, 0 ; index into strings
mov ecx, SIZEOF plain ; number of chars in strings
lea esi, plain
lea edi, cipher
COPYCHAR:
mov al, [esi]
add al, key
mov [edi], al
inc esi
inc edi
loop COPYCHAR
lea eax, cipher
push eax
call printf ; call printf C function
add esp, 4 ; clean up stack
mov eax, 0 ; exit with
call exit ; return code 0
main ENDP
END
Any help would be appreciated! Thank You!
I use visual studio 2017
Lets say I one assembly file named "Factorial.asm" and I break it into two .asm files named "one.asm" and "two.asm":
Factiorial.asm works just fine.
Factorial.asm contains
.386
.model flat, stdcall
option casemap :none
includelib \masm32\lib\msvcrt.lib
sprintf proto C :vararg
includelib \masm32\lib\user32.lib
MessageBoxA proto :ptr,:ptr,:ptr,:DWORD
includelib \masm32\lib\kernel32.lib
ExitProcess proto :dword
.data
format db "%llu", 13, 10, 0
_title db "Result",13,10,0
.code
main PROC
LOCAL szBuf[9]:byte
mov eax, 15 ; initial value (low-order bits)
xor edx, edx ; initial value's high-order bits are 0
mov ecx, eax ; loop counter
Factorial:
dec ecx ; decrement counter
jz Finished ; when counter == 0, we're done
mov ebx, ecx ; make copy of counter
imul ebx, edx ; high-order bits * multiplier
mul ecx ; low-order bits * multiplier
add edx, ebx ; add high-order product to high-order bits of low-order product
cmp ecx, 1
jg Factorial ; keep looping as long as counter > 1
Finished:
invoke sprintf, addr szBuf, offset format, eax, edx
invoke MessageBoxA, 0, addr szBuf, offset _title, 0
invoke ExitProcess, 0
main ENDP
one.asm contains
.386
.model flat, stdcall
option casemap :none
includelib \masm32\lib\msvcrt.lib
sprintf proto C :vararg
includelib \masm32\lib\user32.lib
MessageBoxA proto :ptr,:ptr,:ptr,:DWORD
includelib \masm32\lib\kernel32.lib
ExitProcess proto :dword
.data
format db "%llu", 13, 10, 0
_title db "Result",13,10,0
.code
main PROC
LOCAL szBuf[9]:byte
mov eax, 15 ; initial value (low-order bits)
xor edx, edx ; initial value's high-order bits are 0
mov ecx, eax ; loop counter
Factorial:
dec ecx ; decrement counter
jz Finished ; when counter == 0, we're done
mov ebx, ecx ; make copy of counter
imul ebx, edx ; high-order bits * multiplier
mul ecx ; low-order bits * multiplier
add edx, ebx ; add high-order product to high-order bits of low-order product
cmp ecx, 1
jg Factorial ; keep looping as long as counter > 1
main ENDP
two.asm contains
Finished:
invoke sprintf, addr szBuf, offset format, eax, edx
invoke MessageBoxA, 0, addr szBuf, offset _title, 0
invoke ExitProcess, 0
How would I link "one.asm" and "two.asm" using Visual Studio 2017. Or in other words, call labels from separate .asm files?
Use the directive extrn to declare functions outside of the current source file:
extrn foo:proc
You can optionally use public to declare local functions as public, but I think functions are public by default.
Since VS2015, printf is now inlined with C / C++ code, at least in the case of 64 bit builds. One way to deal with this is to have a C / C++ source file that makes a reference to printf, in which case the assembly code can then access printf. I don't know if this applies to sprintf also. You'll get a link error if this is an issue.
There are usually three types of objects that you need to transfer information across files to.
Proc defined in source file called for in user file : By default, in masm, all procs are global. So, the source file needs no declaration, the user file needs a declaration :
extern <proc_name> : proc
Variable defined in source file and called by a procedure in user file : In this situation, the source file needs a declaration
public <var_name>
and the user file must contain the declaration :
extern <varname> : var_size ; where var_size is word, qword ymmword...
It is NOT mandatory that the declaration size must match the extern size. However, consequences of not ensuring this match are usually expensive. Also, if a variable has been declared as an extern, and subsequently, not used in that file, it still must match a corresponding public declaration in some file, otherwise linker will fail.
Label defined in source file and jumped to from a user file : identical treatment as a variable (case 2) is treated
Trust this helps.
.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 ; high byte
mov al,byte ptr bigEndian+1 ; 2nd byte
mov word ptr littleEndian+2,ax ; high word
mov ah,byte ptr bigEndian+2 ; 3rd byte
mov al,byte ptr bigEndian+3 ; 4th byte
mov word ptr littleEndian,ax ; low word
invoke ExitProcess,0
main endp
end main
First time using VS2013 and I cannot figure out why this will not run. It tells me in the bottom console 1 fail and a pop-up states "Unable to start program"
Look at the error page, when that error pop-up appears it means that you have not set-up Visual Studio correctly. In this case, the Kip Irvine was no downloaded and that there was no space in the Handlers section in setup.
Comment #
Using Programming Exercise 6 in Chapter 4 as a starting point,
write a program that generates the first 47 values in the Fibonacci
series, stores them in an array of doublewords, and writes the
doubleword array to a disk file.
#
INCLUDE c:\Irvine\Irvine32.inc
FIB_COUNT = 47 ; number of values to generate
.data
fileHandle DWORD ?
filename BYTE "fibonacci.bin",0
array DWORD FIB_COUNT DUP(?)
.code
main2sub PROC
; Generate the array of values
mov esi, OFFSET array
mov ecx, LENGTHOF array
call generate_fibonacci
; Create the file, call CreateOutputFile
mov edx,OFFSET filename
call CreateOutputFile
mov fileHandle, eax
; Write the array to the file, call WriteToFile
mov eax, fileHandle
mov edx, OFFSET array
mov ecx, FIB_COUNT * 4
call WriteToFile
; Close the file, call CloseFile
mov eax, fileHandle
call CloseFile
exit
main2sub ENDP
;------------------------------------------------------------
generate_fibonacci PROC USES eax ebx ecx edx
;
; Generates fibonacci values and stores in an array.
; Receives: ESI points to the array,
; ECX = count
; Returns: nothing
;------------------------------------------------------------
mov ebx, 1
mov ecx, 0
L1:
add ebx, ecx
mov [esi], eax
call WriteDec
call Crlf
inc esi
xchg ebx, eax
loop L1 ;end of looping
ret
generate_fibonacci ENDP
END main2sub
It is my first semester learning about Assembly Language. Im not sure what to do with this error message "fatal error LNK1120: 1 unresolved externals". Can anyone help me out?
The linker couldn't find the library-files Irvine32.lib, Kernel32.Lib and/or User32.Lib. They are in the same folder as Irvine32.inc
The easiest way is to inform ML about those libraries with a MASM-directive. Insert following three lines right behind the INCLUDE c:\Irvine\Irvine32.inc:
INCLUDELIB c:\Irvine\Irvine32.lib
INCLUDELIB c:\Irvine\Kernel32.lib
INCLUDELIB c:\Irvine\User32.lib