x86 Program received signal SIGSEGV, Segmentation fault during debugging MASM32 assembly - debugging

I am tasked with writing my first assembly code which takes a number between 1-12 entered by the user and outputs the factorial. I need to write 3 procedures one for the input, one to calculate factorial and one to print the result. I believe I have written it correctly (I didn't) but after getting the input from the user, the program terminates. I never see the result of my "Print" procedure. When trying to debug my code I get the error:
Program received signal SIGSEGV, Segmentation fault.
This error comes right after the first step of "invoke input"
Here is my complete code :
include c:\asmio\asm32.inc
includelib c:\asmio\asm32.lib
includelib c:\asmio\User32.lib ; SASM files for I/O
includelib c:\asmio\Kernel32.lib ; SASM files for I/O
input proto ; 0 parameters
Factorial proto nvx: dword ; 1 parameter
Print proto nax: dword, nf: dword ; 2 parameters
; -------------------------------------------------------
.const ; Section to declare and initialize constants
NULL = 0
; -------------------------------------------------------
.data ; Section to declare and initialize variables
nvx dword ?
nfx dword ?
nf dword ?
ask byte "Enter a number between 1-12: ", NULL
fin byte "! is ", NULL
; -------------------------------------------------------
.code ; The actual code begins here: Main program
main proc ; Just like C++ this is the main program
start:
invoke input
mov nvx, eax
invoke Factorial, nvx
mov nfx, eax
invoke Print, nvx, nfx
ret 0 ; need this line to return to caller
main endp ; End of the procedure main
; -------------------------------------------------------
input proc
mov edx, OFFSET ask
call WriteString
call ReadInt
ret
input endp
; -------------------------------------------------------
Factorial proc USES ECX EBX nv: dword
mov ecx, nv ;start loop counter at value given by user because we need to multiply this many times to find the factorial.
mov ebx, nv ; hold value of nv as divisor
inc nv ; This is to account for 0! We increment by one and after the loop divide by nv
mov eax, nv ; stores the largest number for multiplication
L1:
dec nv ; becomes next largest number
mul nv ; multiplication
mov eax, edx ; stores product into eax for next multiplication
loop L1
inc ebx
cdq
idiv ebx ; divide final product by original number + 1 for the correct factorial
ret
Factorial endp
Print proc nax: dword, na: dword
mov eax, nvx
call WriteString
mov eax, OFFSET fin
call WriteString
mov eax, na
call WriteString
ret
Print endp
end main ; End of the entire program
; -------------------------------------------------------

Related

Can I get the screenshots of the assembly codes?

I know this is outside the scope of the community but I had nowhere else to turn to. I need screenshots of Visual Studio after running the following programs for an assignment. My PC died and it is due in a few hours. There are two MASM programs and they are both interactive, any logical variables will do. You can send the link of the images to:mihijek116#vapaka.com (attachments will not work) if the question is closed. Thanks in advance
INCLUDE Irvine32.inc
.data
fname BYTE 16 Dup(?)
age dword ?
np BYTE 'Enter Name:',0dh, 0ah,0
ap BYTE 'Enter Age:',0dh, 0ah,0
yn BYTE 'Your name is ',0
yy BYTE ' born in ',0
cy dword 2022
dob dword ?
.code
main PROC
mov edx, offset np
call WriteString
mov edx, offset fn
mov ecx, Sizeof fn
call readstring
call Crlf
mov edx, offset ap
call WriteString
call readInt
mov age, eax
mov eax, cy
sub eax, age
mov yob, eax
mov edx, offset yn
call WriteString
mov edx, offset fn
call WriteString
mov edx, offset yy
call WriteString
mov eax, dob
call WriteDec
call Crlf
call WaitMsg
exit
main ENDP
END main
INCLUDE Irvine32.inc
.data
two dword 2 ; store two
three dword 3 ; store three
c dword 1 ; store 1
n dword ? ; n variable
answer dword ? ; answer variable
a1 dword ? ; store 2n^2
a2 dword ? ; store 3n
pr BYTE 'Enter n:',0dh, 0ah,0 ; n prompt
eq BYTE 'ans= ',0 ; ans
.code
n2n PROC ; 2*n*n
mov eax, two
mov ecx, n
mul ecx
mov ecx,n
mul ecx
mov a1,eax
ret
n2n ENDP
n3 PROC ; 3n
mov eax, three
mov ecx, n
mul ecx
mov a2,eax
ret
3n ENDP
main PROC
mov edx, offset pr
call WriteString ; Ask user for n
call readInt
mov n, eax ; Store user input in n
call n2n ; call procedure n2n
call 3n ; call procedure n3
mov ebx, a1
add ebx, a2
add ebx, c
mov answer, ebx ; store result in answer
mov edx, offset eq
call WriteString
mov eax, answer
call WriteDec
call WaitMsg
exit
main ENDP
END main

Display First N Fibonacci Numbers in x86 asm [duplicate]

This question already has answers here:
MASM x86 Adding two ints
(1 answer)
What is the Irvine32 library and why do we use it?
(1 answer)
x86 Assembly Input a set of Integers
(1 answer)
Closed 2 years ago.
I want to generate the 1st N fibonacci numbers in x86 asm using the Irvine Library. That means whenever I will give N = 5, it should print : 0,1,1,2,3, But whenever I run it suppose with N =5 then it gives output as : 0,1,2,3,4.
Below is my program
TITLE MASM Irvine
INCLUDE Irvine32.inc
.data
message1 BYTE "The first ",0
message2 BYTE " numbers in the Fibonacci sequence are the following.",0
N DWORD 10
intialVal WORD 0,1
.code
main PROC
call Clrscr ; clears screen
mov edx,OFFSET message1
call WriteString ; display message1
mov eax, N
call WriteDec ; display num
mov edx,OFFSET message2
call WriteString ; display message2
call Crlf ; new line
mov eax,0
mov bx, [intialVal]
mov cx, [intialVal + 2]
StartLoop:
mov edx,0 ;setting edx to 0 every time
add dx,bx ;adding bx to dx
add dx,cx ;adding cx to dx
call WriteDec
call Crlf ;trying to print dx
mov bx,cx ;moving numbers. so now cx goes to bx
mov cx,dx ;dx goes to cx
inc eax ;increment eax (as a counter)
cmp eax,N ;compare to variable N
jne StartLoop ;if eax = N exit loop, else jump to start of loop
exit
main ENDP
END main

Handle user input overflow to ReadConsoleA. Clear previous input? [duplicate]

This question already has an answer here:
x86 MASM Assembly - Input Buffer holds old input despite FlushConsoleInputBuffer
(1 answer)
Closed 2 years ago.
I would like to get user input from the console using the ReadConsoleA prototype in /masm32/lib/kernel32.lib.
If the user inputs less than the maximum number of characters, the program runs fine, but if they give too many, the program uses the extra for the next input.
Language: MASM x86
Computer: Windows 10 x64
Driver.asm
.386
.model flat, C
.stack 100h
INCLUDELIB /masm32/lib/kernel32.lib
GetStdHandle PROTO Near32 STDCALL, nStdHandle: DWORD
WriteConsoleA PROTO Near32 STDCALL, handle:DWORD, lpBuffer:PTR BYTE, nNumberOfBytesToWrite:DWORD, lpNumberOfBytesWritten:PTR DWORD, lpReserved:DWORD
ReadConsoleA PROTO Near32 STDCALL, handle:DWORD, lpBuffer:PTR BYTE, nNumberOfCharsToRead:DWORD, lpNumberOfCharsRead:PTR DWORD, lpVoid:DWORD
ExitProcess PROTO STDCALL, dwExitCode:DWORD
StrInput PROTO, addrStr:DWORD, dNumCharsToRead:DWORD
StrPrint PROTO, addrStr:DWORD
StrLen PROTO, addrStr:DWORD
.DATA
strPromptName db "Enter your name: ", 0
strInputName db 10 DUP(0)
strNewLine db 13, 10, 0
.CODE
Main PROC
MOV EAX, 0
; Ask for name, store it, print it, new line
INVOKE StrPrint, ADDR strPromptName
INVOKE StrInput, ADDR strInputName, LENGTHOF strInputName
INVOKE StrPrint, ADDR strInputName
INVOKE StrPrint, ADDR strNewLine
; Ask for name, store it, print it, new line
INVOKE StrPrint, ADDR strPromptName
INVOKE StrInput, ADDR strInputName, LENGTHOF strInputName
INVOKE StrPrint, ADDR strInputName
INVOKE StrPrint, ADDR strNewLine
INVOKE ExitProcess, 0
Main ENDP
StrInput PROC PUBLIC addrStr:DWORD, dNumCharsToRead:DWORD
.DATA
dNumCharsRead dd ? ; Holds the number of chars read from console
.CODE
PUSHAD ; Store all registers, don't trust others' functions
INVOKE GetStdHandle, -10 ; Standard input = -10, handle in EAX
INVOKE ReadConsoleA, EAX, addrStr, dNumCharsToRead, OFFSET dNumCharsRead, 0
MOV EDI, addrStr ; Goto front of string
ADD EDI, dNumCharsRead ; Goto just after last inputted char
SUB EDI, 2 ; Go back 2, to carriage return char
MOV BYTE PTR [EDI], 0 ; Change to 0 for null termination
POPAD ; Restore all registers
RET ; No return value, return to caller
StrInput ENDP
StrPrint PROC PUBLIC addrStr:DWORD
PUSHAD ; Store all registers, don't trust others' functions
INVOKE StrLen, addrStr ; Length in ECX
DEC ECX ; Don't print null terminator
INVOKE GetStdHandle, -11 ; Standard output = -11, handle in EAX
INVOKE WriteConsoleA, EAX, addrStr, ECX, 0, 0
POPAD ; Restore all registers
RET ; No return value, return to caller
StrPrint ENDP
StrLen PROC PUBLIC uses AX EDI addrStr:DWORD
MOV EDI, addrStr ; Store address for scanning
XOR AL, AL ; Store null term for scanning
MOV ECX, -1 ; ECX = len, will decrement over string (neg len)
CLD ; Clear direction flag, search forward
REPNE SCASB ; While char not 0, continue scanning
NEG ECX ; Make length positive
DEC ECX ; Off by one
RET ; Len in ECX, return to caller
StrLen ENDP
END Main
Good terminal output
Enter your name: abcdef << Allowed user input
abcdef
Enter your name: new << Allowed user input
new
Press any key to continue . . .
User input overflow
Enter your name: reallylongname << Allowed user input
reallylo
Enter your name: name << Didn't allow user input
Press any key to continue . . . << Also didn't print
Thank you Michael Petch! I changed StrInput and added FlushInputBuffer PROC as shown below.
Any tips or suggestions as to cleaner code is appreciated, but my question is suitably answered.
StrInput PROC PUBLIC addrStr:DWORD, dNumCharsToRead:DWORD
.DATA
dNumCharsRead dd ? ; Holds the number of chars read from console
.CODE
PUSHAD ; Store all registers, don't trust others' functions
INVOKE GetStdHandle, -10 ; Standard input = -10, handle in EAX
INVOKE ReadConsoleA, EAX, addrStr, dNumCharsToRead, OFFSET dNumCharsRead,
MOV EDI, addrStr ; Goto front of string
ADD EDI, dNumCharsRead ; Goto last inputted char
DEC EDI ; Back one, to last inputted char
CMP BYTE PTR [EDI], 0Ah ; Check if is line feed char
JE done ; If is, done
INVOKE FlushInputBuffer ; Else, clear all input
done:
DEC EDI ; Goto 0Dh char (2nd last char)
MOV BYTE PTR [EDI], 0 ; Set to zero for null termination
POPAD ; Restore all registers
RET ; No return value, return to caller
StrInput ENDP
FlushInputBuffer PROC
.DATA
strDummy db 255 DUP (?) ; Holds input overflow, dummy variable
dNumRead dd ? ; Holds number of chars read
.CODE
PUSHAD ; Store all registers, don't trust others' functions
flush_loop:
INVOKE GetStdHandle, -10 ; Standard input = -10, handle in EAX
INVOKE ReadConsoleA, EAX, ADDR strDummy, 255, ADDR dNumRead, 0
MOV EAX, dNumRead ; Store num read for comparison
CMP EAX, 255 ; If is less than 255, done reading
JE flush_loop ; Else keep reading
POPAD ; Restore all registers
RET ; Return to caller
FlushinputBuffer ENDP

How to print signed integer in x86 assembly (NASM) on Mac

I found an implementation of unsigned integer conversion in x86 assembly, and I tried plugging it in but being new to assembly and not having a debugging env there yet, it's difficult to understand why it's not working. I would also like it to work with signed integers so it can capture error messages from syscalls.
Wondering if one could show how to fix this code to get the signed integer to print, without using printf but using strprn provided by this answer.
%define a rdi
%define b rsi
%define c rdx
%define d r10
%define e r8
%define f r9
%define i rax
%define EXIT 0x2000001
%define EXIT_STATUS 0
%define READ 0x2000003 ; read
%define WRITE 0x2000004 ; write
%define OPEN 0x2000005 ; open(path, oflag)
%define CLOSE 0x2000006 ; CLOSE
%define MMAP 0x2000197 ; mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t offset)
; szstr computes the lenght of a string.
; rdi - string address
; rdx - contains string length (returned)
strsz:
xor rcx, rcx ; zero rcx
not rcx ; set rcx = -1 (uses bitwise id: ~x = -x-1)
xor al,al ; zero the al register (initialize to NUL)
cld ; clear the direction flag
repnz scasb ; get the string length (dec rcx through NUL)
not rcx ; rev all bits of negative -> absolute value
dec rcx ; -1 to skip the null-term, rcx contains length
mov rdx, rcx ; size returned in rdx, ready to call write
ret
; strprn writes a string to the file descriptor.
; rdi - string address
; rdx - contains string length
strprn:
push rdi ; push string address onto stack
call strsz ; call strsz to get length
pop rsi ; pop string to rsi (source index)
mov rax, WRITE ; put write/stdout number in rax (both 1)
mov rdi, 1 ; set destination index to rax (stdout)
syscall ; call kernel
ret
; mov ebx, 0xCCCCCCCD
itoa:
xor rdi, rdi
call itoal
ret
; itoa loop
itoal:
mov ecx, eax ; save original number
mul ebx ; divide by 10 using agner fog's 'magic number'
shr edx, 3 ;
mov eax, edx ; store quotient for next loop
lea edx, [edx*4 + edx] ; multiply by 10
shl rdi, 8 ; make room for byte
lea edx, [edx*2 - '0'] ; finish *10 and convert to ascii
sub ecx, edx ; subtract from original number to get remainder
lea rdi, [rdi + rcx] ; store next byte
test eax, eax
jnz itoal
exit:
mov a, EXIT_STATUS ; exit status
mov i, EXIT ; exit
syscall
_main:
mov rdi, msg
call strprn
mov ebx, -0xCCCCCCCD
call itoa
call strprn
jmp exit
section .text
msg: db 0xa, " Hello StackOverflow!!!", 0xa, 0xa, 0
With this working it will be possible to properly print signed integers to STDOUT, so you can log the registers values.
https://codereview.stackexchange.com/questions/142842/integer-to-ascii-algorithm-x86-assembly
How to print a string to the terminal in x86-64 assembly (NASM) without syscall?
How do I print an integer in Assembly Level Programming without printf from the c library?
https://baptiste-wicht.com/posts/2011/11/print-strings-integers-intel-assembly.html
How to get length of long strings in x86 assembly to print on assertion
My answer on How do I print an integer in Assembly Level Programming without printf from the c library? which you already linked shows that serializing an integer into memory as ASCII decimal gives you a length, so you have no use for (a custom version of) strlen here.
(Your msg has an assemble-time constant length, so it's silly not to use that.)
To print a signed integer, implement this logic:
if (x < 0) {
print('-'); // or just was_negative = 1
x = -x;
}
unsigned_intprint(x);
Unsigned covers the abs(most_negative_integer) case, e.g. in 8-bit - (-128) overflows to -128 signed. But if you treat the result of that conditional neg as unsigned, it's correct with no overflow for all inputs.
Instead of actually printing a - by itself, just save the fact that the starting number was negative and stick the - in front of the other digits after generating the last one. For bases that aren't powers of 2, the normal algorithm can only generate digits in reverse order of printing,
My x86-64 print integer with syscall answer treats the input as unsigned, so you should simply use that with some sign-handling code around it. It was written for Linux, but replacing the write system call number will make it work on Mac. They have the same calling convention and ABI.
And BTW, xor al,al is strictly worse than xor eax,eax unless you specifically want to preserve the upper 7 bytes of RAX. Only xor-zeroing of full registers is handled efficiently as a zeroing idiom.
Also, repnz scasb is not fast; about 1 compare per clock for large strings.
For strings up to 16 bytes, you can use a single XMM vector with pcmpeqb / pmovmskb / bsf to find the first zero byte, with no loop. (SSE2 is baseline for x86-64).

fatal error LNK1120: 1 unresolved externals for assembly language using VS2010

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

Resources