Addition Loop in Visual Studio - visual-studio-2010

I'm trying to make a loop that adds all the numbers between 1 and 20 ( 1+2+3+4+5....+20) and to my understanding it goes something like this but it says there was a build error when i try to run it. I thought ax is the number that you start with and then ecx was the number of times that the loop will perform then i increment a to make the number 1 higher each time. Can anyone see anything wrong?
.data
a = 0
.code
main PROC
mov ax, 0
mov ecx, 20
addLoop:
inc a
add ax,ax
loop addLoop
call DumpRegs
exit
main ENDP
END main

Related

Random number generator crashing in assembly

Found this code here on stackoverflow, I understood how it works and tried implementing it. It crashes at the INT 1AH instruction and I don't know why.
When I run it in ollydbg, it stops at the same line.
I also tried the random number generator function rand(void) but it always gives me the same numbers whenever I rerun the code. (different 3 numbers if I call it 3 times in a row, but still the same ones with every rerun)
.386
.model flat, stdcall
includelib msvcrt.lib
extern exit: proc
extern printf: proc
extern rand: proc
public start
.data
decimal_format DB "%d",0ah
.code
start:
mov ah, 00h
int 1ah
mov ax,dx
mov dx,0
mov cx,10
div cx
mov ah,2h
int 21h
push edx
push offset decimal_format
call printf
add esp,8
push 0
call exit
end start
If you are writing Win32 programs you can't call BIOS and DOS services like Int 1ah, Int 10h, Int 21h etc. That will crash your application as Win32 programs do not have access to those services.
The basic rand and srand in the Windows C library (MSVCRT.LIB) are based on a linear congruent generator (LCG) pseudo-random number generator (PRNG). This formula relies on a seed value to set the initial state of the PRNG. The initial state when your program executes will always be the same each time the program is restarted. Every call to rand will then reproduce a pseudo-random number, but the numbers will be the same sequence each time the program is run.
srand can be used to change the seed value of the PRNG. Changing the seed value will alter the numbers rand will produce but they will always be the same sequence of numbers given the same seed. What you need is a mechanism to set the seed value to a different value each time the program is run. You can use the C library time function with a NULL(0) parameter to get the number of seconds since midnight January 1, 1970. This value should be different as long as your program isn't run quickly in such a way it executes within the same second. This is generally good enough.
You can then pass the value returned by time(0) in EAX to srand to set the seed value. Only call srand once when your program starts. From that point on you should be able to call rand to get a new random number. rand returns value between 0 and RAND_MAX and RAND_MAX is 32767.
This sample code does srand(time(0)) to initialize the seed and then loops 10 times printing out a different random number retrieved by calls to rand. Each time you run the program the output should be different.
.386
.model flat, C
includelib msvcrt.lib
extern exit: proc
extern printf: proc
extern rand: proc
extern srand: proc
extern time: proc
.data
decimal_format DB "%d", 0ah, 0
; Ensure string is NUL(0) terminated
.code
main PROC
push ebx ; Save callee saved (non-volatile) registers that we use.
; EBX, EBP, ESI, EDI, ESP are non-volatile. For each
; one we clobber we must save it and restore it before
; returning from `main`
push 0
call time ; EAX=time(0)
add esp, 4
push eax ; Use time as seed
call srand ; srand(time(0))
add esp, 4
mov ebx, 10 ; Loop 10 times
loopit:
call rand ; Get a random number between 0 and 32767 into EAX
push eax
push offset decimal_format
call printf ; Print the random number
add esp,8
dec ebx
jnz loopit ; Loop until the counter EBX reaches 0
pop ebx ; Restore callee saved registers
xor eax, eax ; Return 0 from our program
ret
main ENDP
END
Some other important changes. I use the C (CDECL) calling convention (via .model flat, C) which automatically handles decorating main PROC with an underscore in 32-bit code. I have also changed start to main and changed end start to just end. We don't want to use end main either because that directive will make main the entry point to our code and will skip the C runtime initialization that usually has to be done prior to main being called. Failure to have the C runtime initialization called may make C library function work unexpectedly or crash altogether.
When the code finishes I do a ret to return to the C startup code which will exit for us. The code also preserves the non-volatile (callee saved) registers. See the Microsoft 32-bit CDECL calling convention for more information.

How do I check if my assembly 8086 program runs well

I want to put numbers from 0 - 9 to memory cells 400h to 409h.
So for example at 400h -> 0 (put 0) and at 401h -> 1 (put 1) ..... 409h (put 9).
This is my code so far: (I dont know if it works)
IDEAL
MODEL small
STACK 100h
DATASEG
;----------
;----------
CODESEG
start:
mov ax , #data
mov ds , ax
mov es, ax
;----------
mov si , 400h
mov cx , 10
mov al , 0
agian:
mov [si],al
inc si
inc al
loop agian
;--------
exit:
mov ax,4c00h
int 21h
END start
There's a very simple way to see if your program works. Just write the values in the video memory. That way you'll know if it works.
start:
mov ax, 0B800h ;NEW
mov ds, ax
mov es, ax
;----------
mov si, 400h
mov cx, 10
mov al, 48 ;NEW value 0 -> character 0
agian:
mov [si], al
add si, 2 ;NEW 1 character occupies 2 bytes in video memory
inc al
loop agian
mov ah,00h ;NEW wait for a keystroke so you can actually see
int 16h ;NEW ... the output
If you can invest the time you could learn to use the DOS utility DEBUG.EXE. Amongst other things it allows you to single step your program and view memory .
The easiest way to check if your ASM code is working the way you expect is to run it in a debugger. If you're running on Windows, OllyDbg 2 would be a good candidate — it will show you the current values of the registers, state of the stack, etc., so you can see how they change as you step through your code. You can modify the code from inside OllyDbg too.
You can write breakpoints in your code with the int 3 instruction, or use the debugger to place breakpoints at runtime.

Solving Binary Bomb Phase 5 [duplicate]

So I am working on a Binary Bomb assignment and have gotten stuck. Tried looking at other questions and guides but mine seems to be completely different from what is described in other questions and guides I found on the web.
The phase only takes 2 unsigned ints for input. Here it is disassembled in gdb after being run with 11 2 as input.
Dump of assembler code for function phase_5:
0x08048ccc <+0>: push %ebp
0x08048ccd <+1>: mov %esp,%ebp
0x08048ccf <+3>: push %esi
0x08048cd0 <+4>: push %ebx
=> 0x08048cd1 <+5>: sub $0x20,%esp
0x08048cd4 <+8>: lea -0x10(%ebp),%eax
0x08048cd7 <+11>: mov %eax,0xc(%esp)
0x08048cdb <+15>: lea -0xc(%ebp),%eax
0x08048cde <+18>: mov %eax,0x8(%esp)
0x08048ce2 <+22>: movl $0x8049b0a,0x4(%esp)
0x08048cea <+30>: mov 0x8(%ebp),%eax
0x08048ced <+33>: mov %eax,(%esp)
0x08048cf0 <+36>: call 0x8048788 <__isoc99_sscanf#plt>
0x08048cf5 <+41>: cmp $0x1,%eax
0x08048cf8 <+44>: jg 0x8048cff <phase_5+51>
0x08048cfa <+46>: call 0x80492b6 <explode_bomb>
0x08048cff <+51>: mov -0xc(%ebp),%eax
0x08048d02 <+54>: and $0xf,%eax
0x08048d05 <+57>: mov %eax,-0xc(%ebp)
0x08048d08 <+60>: cmp $0xf,%eax
0x08048d0b <+63>: je 0x8048d36 <phase_5+106>
0x08048d0d <+65>: mov $0x0,%ecx
0x08048d12 <+70>: mov $0x0,%edx
0x08048d17 <+75>: mov $0x8049960,%ebx
0x08048d1c <+80>: add $0x1,%edx
0x08048d1f <+83>: mov (%ebx,%eax,4),%eax
0x08048d22 <+86>: add %eax,%ecx
0x08048d24 <+88>: cmp $0xf,%eax
0x08048d27 <+91>: jne 0x8048d1c <phase_5+80>
0x08048d29 <+93>: mov %eax,-0xc(%ebp)
0x08048d2c <+96>: cmp $0xb,%edx
0x08048d2f <+99>: jne 0x8048d36 <phase_5+106>
0x08048d31 <+101>: cmp -0x10(%ebp),%ecx
0x08048d34 <+104>: je 0x8048d3b <phase_5+111>
0x08048d36 <+106>: call 0x80492b6 <explode_bomb>
0x08048d3b <+111>: add $0x20,%esp
0x08048d3e <+114>: pop %ebx
0x08048d3f <+115>: pop %esi
0x08048d40 <+116>: pop %ebp
0x08048d41 <+117>: ret
For the line 0x08048d17 <+75>: mov $0x8049960,%ebx
I used
x/16b 0x8049960
gdb and it tells me
0x8049960 array.2954: 10 0 0 0 2 0 0 0
0x8049968 array.2954+8: 14 0 0 0 7 0 00
When I go through the program using until until I get to
0x08048d31 <+101>: cmp -0x10(%ebp),%ecx
%edx = 11, %ecx = 82, and %ebp-0x10 = 2 (used print to get values for first two and x/d $ebp-0x10 for last one)
Because 82 != 2 it just goes to call explode_bomb.
From what I understand it is reading in my 2 numbers, making sure I entered 2 at <+41>.
Then it grabs the first number from the array which in this case is 10 and puts it into $eax at +=<+51>. Then it puts eax into -0xc($ebp) at <+57>.
Then it checks to make sure $eax isn't 15 at <+60>, goes on to set $ecx, and $edx to 0. It then passes the pointer to the array to $ebx at <+75>.
Then it enters a loop from <+80> to <+91> but I am not sure what it is really doing. I get that it increments $edx by 1 and the loop is exited when $eax is 15, but I cant figure out how the rest of the stuff works out.
Am I understanding it correctly up to the loop part? And, if someone wouldn't mind explaining what is happening between <+80> and <+91> I would be very grateful.
p.s. Sorry if my formatting is wrong.
Then it grabs the first number from the array which in this case is
10 and puts it into $eax at +=<+51>.
Wrong. <+51> reads the first number you entered, not the first number from the array. It's then masked into the 0..15 range by discarding the top bits, and is written back to the local variable where it came from. It also lives on in eax, of course.
The array contains 4 byte integers and there are 15 of them. As such you can print it using x/15wd.
Now to the loop. edx is obviously just keeping track of the iteration count, no surprise there. <+83> is the interesting part: it replaces eax with the value of the array item whose index eax currently holds. That is eax = array[eax]. ecx is of course just summing up the array elements you have visited, that's again easy. The exit condition is when you hit the array item that has value 15.
What it all boils down is that this array is really a linked list. The end of the list is marked by a 15. The first number you enter is used as a starting point for list traversal. It should be selected such that you have 11 elements until the end of the list (see <+96>). The second input number should equal the sum of the array items visited.

Using Windows Registry Functions in Assembly Language

I am trying to use the Windows registry functions to create a registry key in the 'Software\Microsoft\Windows\CurrentVersion\Run' key in assembly language. My program crashes and displays a Windows error message. Here is the code:
includelib \Masm64\Lib\Kernel32.lib
includelib \Masm64\Lib\Advapi32.lib
extrn ExitProcess : proc
extrn RegCreateKeyExA : proc
dseg segment para 'DATA'
rhdl dd 0
sbky db 'Software\Microsoft\Windows\CurrentVersion\Run\startupprogram.exe', 0
dseg ends
cseg segment para 'CODE'
start proc ;Use link.exe to define entry point
sub rsp, 28h
push 0
push qword ptr [rhdl]
push 0
push 0
push 0
xor r9d, r9d
xor r8d, r8d
lea rdx, [sbky]
mov rcx, 8000001h
call RegCreateKeyExA
xor ecx, ecx ; exit code = 0
call ExitProcess
start endp
cseg ends
end
I would appreciate your help. Perhaps I have disregarded the Windows calling convention?
In the Win64 x64 calling convention you have to reserve stack slots for the four arguments passed in the registers:
From http://msdn.microsoft.com/en-us/library/ms235286.aspx:
The caller is responsible for allocating space for parameters to the callee, and must always allocate sufficient space for the 4 register parameters, even if the callee doesn’t have that many parameters.
So the RegCreateKeyExA() function is treating the last four things you pushed onto the stack as locations reserved for the four register arguments, then is trying to get the other arguments from the first push 0 then whatever random garbage is in the area of the stack you reserved with the sub rsp,28h.
Try:
push 0
push qword ptr [rhdl]
push 0
push 0
push 0
sub rsp, 20h ; reserve slots for arguments passed in regs
xor r9d, r9d
xor r8d, r8d
lea rdx, [sbky]
mov rcx, 8000001h
call RegCreateKeyExA
It's not something I've worked on but I have a non MASM example
SYS "SetWindowPos", #hwnd%, 0, xpos%, ypos%, 0, 0, 5
becomes
push 5
push 0
push 0
push ypos%
push xpos%
push 0
push #hwnd%
call "SetWindowPos"
There's an order of assembly by a compiler where it searches for internal calls within the program then looks for external calls (ie windows ones)
It all boils down to how your compiler operates for these things
Probably easier to experiment with simpler calls to start with
push 16d
call "MessageBeep"
and
push 8d
call "MessageBeep"
for example
Two beeps
push 8
call "MessageBeep"
mov eax,1
.ag
inc eax
cmp eax,&FFFFFFF
jb ag
push 16
call "MessageBeep"
etc

How do I print 0,2,4,6,... in assembly language?

I have an assignment from my comp. system org. subject and unfortunately I'm kind of new when it comes to assembly language. I'm supposed to write a program that displays the numbers 0,2,4,6,8,10 respectively. How would I go about this?
Maybe this'll answer my question: (Reactions please)
.model small
.stack 100H
.data
.code
call proc
mov cx,5
mov dx,0
L1:
mov bx,2
add dx,bx
mov ah,02h
loop L1
int 21
endp
Go see your lecturer and/or tutor and ask for advice. That's what they're there for. You haven't given us anywhere near enough info to help you out.
Here's what I think your ABCD program should look like. I suggest you use it as a baseline to try to make a 0 2 4 ... version.
model proc
.stack 100H
.data
.call
main proc
mov cx,10 ; 10 loops only.
mov dx,40h ; start dx at 'A' - 1.
L1:
inc dx ; move to next character.
mov ah,02h ; int 21,02 is print character.
int 21h
loop L1 ; loop until cx is 0
mov ax,4c00h ; int 21,4c is exit with al holding exit code.
int 21
endp
When you've at least had a go at converting this, post the code and we'll critique what you've done.
If you're taught something, it never lasts but, if you learn something, it lasts forever (alcohol-addled braincells notwithstanding :-).
Int 21 is the DOS interrupt which allows assembler programs to use various DOS functions. It's conceptually a huge switch statement based on the AH register which is why you'll see things like Int 21 Fn 02, which means execute mov ah,2 followed by int 21.
Int 21 Fn 02 will take the contents of DL and output that to the screen. So the sequence:
mov ah,02h
mov dl,41h
int 21h
will output the 'A' character (0x41).
Similarly, Int 21 Fn 4c will exit the current running process.
I'm sure your class gave you some education here.
Can you code enough assembly to print one or two numbers?
Can you code enough to calculate the numbers, even if you can't print them?
Post that much code, and you may find help here.
Otherwise, you're asking others to actually do your homework for you.
Assembly language is a symbolic representation of the numeric machine codes and other constants needed to program a particular CPU (or architecture). So assembly language for Macs (most recently Intel's X86) is different from that used to on the iPhone - ARM.
Your teacher is also probably expecting you to realise the difference between the binary form of the number you will count with, and the ASCII format you will use to display to the screen.
You do know there is more than one flavor of "Assembly Language."
You can do it exactly like the program which prints A, B, C, D, etc.: except that instead of starting at 'A', start at '0; and instead of increasing by 1 each time (from 'A' to 'B'), increase by 2 (from '0' to '2').
After printing '0', '2', '4', '6', and '8', the next number that you want to print is '10'.
To print '10', you can print '1' followed by '0'. Or, instead of invoking int 21 with ah=2 (which prints one character at a time), you can set ah=9 to print a string (set ds:dx to a block of memory which contains "10$").
Later you suggested the following solution and asked for criticism:
.model small
.stack 100H
.data
.code
main proc
call defineuser1
call defineuser2
mov cx,5
userdefine1 proc
L1:
mov dx,0
mov bx,2
add dx,bx
mov ah,02h
loop L1
int 21h
endp
userdefine2 proc
mov ah, 4ch
int 21h
userdefine2
endp
My criticisms are as follows:
defineuser1 doesn't exist (I think you mean userdefine1)
setting cx needs to be inside (not before) the procedure
invoking int 21 needs to be inside (not outside) the loop
you need special handling for "10" as I mentioned above
There's a difference between '0' (the ASCII character/digit) and 0 (the number) ... you need to print the character/digit, not the number
You need to learn to test your code (write it, step through it with debugger, and debug it), preferably before you post questions about it.
You would have a counter beginning at zero and repeatedly increment it by two, printing the result.
.model small
.stack 100H
.code
.data
var2 DB "10$"
main proc
mov cx,4
mov ax,0
mov dl,al
add dl,30h
mov ah,02h
int 21h
mov ax,0
var1:
add ax,2
mov dl,al
add dl,30h
mov bx,ax
mov ah,2h
int 21h
mov ax,bx
loop var1
mov ax,#data
mov ds,ax
mov dx,offset var2
mov ah,09h
int 21h
main endp
end main
I'm new in computer science and when i saw this question i just wanted to try it. I have managed in doing it and here is the code
MOV AX, 0
MOV BX, 2
ADDLOOP:
ADD AX, BX
CMP AX, 10
JE DONE
JMP ADDLOOP
DONE:
Ok. That's my best attempt. Lots of details left out. I should also mention that I have no frigging clue how to print a char to the screen.
Like others have mentioned, you didn't specify which assembly language so I chose x86.
Finally, go talk to your instructors, they'll help you much more than we can.
Are you using a macro for the output?
should be something like...
mov eax, 0
myloop: cmp eax, 10
jg done
output macro eax
add eax, 2
jmp myloop
done:
of course that's for 8086 assembly.

Resources