Assembly question

Joined
Oct 26, 2012
Messages
2,355
Reaction score
1,087
Hello, I want to ask you guys something. I made a Assembly code and I want to know if I really understand it. Can you look at the comments if what I say is correct (like what the line does, whether it's right or wrong)

Code:
org 100h ;This is the address where the program starts

; Start code
mov ecx, 5 ;This moves the int 5 into address ecx, which is used for the amount of times for the loop

.begin: ;Some label
; Message
mov ah,09 ;Puts 09 into ah, this is the index for the print function
mov dx,msg ;Puts the string of variable 'msg' into dx, which is used to be print
int 21h ;Execute the print action
; End Message
loop .begin ;Continues the loop (until address ecx is 0)
mov ah,08 ;Puts 08 into address ah, this is the index for the readkey function (AKA 'pause' keyword for .bat)
int 21h ;Executes the above mov
int 20h ;End of main code

; Some variables?
msg db      "Hello world", 13, 10, "$" ;Creates new variable called 'msg' with string 'Hello World' and a line carriage. The $ is used to end the string.

I'm still learning but I think I start to understand more of it :)
 
I just want to learn Assembly, just because I'm interested in it.
Well, sure. But why DOS specifically? You're effectively learning an API that no modern software uses.
I'd recommend hopping into some nice modern x86-64 assembly. Write a C application to call into your assembly methods, call some C methods from your assembly, etc.
That way you'll be learning stuff that is actually relevant to reverse engineering modern software.

If you REALLY want to have fun with assembly, why not write a virtual machine for some assembly in some other assembly? For example, I wrote a Chip8 virtual machine in x86-64: https://github.com/retep998/Chip8/blob/master/Chip8.asm
 
Well, sure. But why DOS specifically? You're effectively learning an API that no modern software uses.
I'd recommend hopping into some nice modern x86-64 assembly. Write a C application to call into your assembly methods, call some C methods from your assembly, etc.
That way you'll be learning stuff that is actually relevant to reverse engineering modern software.

If you REALLY want to have fun with assembly, why not write a virtual machine for some assembly in some other assembly? For example, I wrote a Chip8 virtual machine in x86-64: https://github.com/retep998/Chip8/blob/master/Chip8.asm

I was just trying.

So actually by 'modern x86-64 assembly' you mean assembly with interaction with C? I know a fairly bit of C already so I think I'll give it a try.
Something like this?

Code:
org 100h

include 'win32ax.inc'

.code
start:
invoke MessageBox,HWND_DESKTOP,"Hello World!","Hello World!",MB_OKCANCEL
invoke Beep,750,300
invoke ExitProcess,0
.end start

(just a quick thing I made to try it out, nothing special)
 
INVOKE is a directive, which means its not actually an asm instruction. If you reverse engineer anything, you will never see invoke used. It's really a shortcut to push the arguments on the stack and/or put them in the correct registers followed by a call and then possibly cleaning up the stack. By using INVOKE, your code becomes easier to compile for different callings conventions, but at the same time you don't see what's actually going on underneath, and you lose some flexibility. Many assemblers even have directives to do conditionals and stuff completely hiding the underlying comparisons and jumps, effectively making the code you write a low level C.
 
I was just trying.

So actually by 'modern x86-64 assembly' you mean assembly with interaction with C? I know a fairly bit of C already so I think I'll give it a try.
Something like this?

Code:
org 100h

include 'win32ax.inc'

.code
start:
invoke MessageBox,HWND_DESKTOP,"Hello World!","Hello World!",MB_OKCANCEL
invoke Beep,750,300
invoke ExitProcess,0
.end start

(just a quick thing I made to try it out, nothing special)

I haven't done x86 Assembly in over a year, so excuse me if it's not correct.

Code:
section .data
strMsg db "Hello, World!", 0 ; Declare message string
strCaption db "Caption", 0 ; Declare caption string

section .code
 ; in C++, the params would be the other way (hWnd, strMsg, strCaption, nType)
PUSH 0 ; Push param 'nType' onto the stack
PUSH strCaption ; Push param 'caption' onto the stack
PUSH strMsg ; Push param 'message' onto the stack
PUSH 0 ; Push param 'hWnd' onto the stack
CALL MessageBoxA ; Call (Execute/Invoke) MessageBoxA
 
I haven't done x86 Assembly in over a year, so excuse me if it's not correct.

Code:
section .data
strMsg db "Hello, World!", 0 ; Declare message string
strCaption db "Caption", 0 ; Declare caption string

section .code
 ; in C++, the params would be the other way (hWnd, strMsg, strCaption, nType)
PUSH 0 ; Push param 'nType' onto the stack
PUSH strCaption ; Push param 'caption' onto the stack
PUSH strMsg ; Push param 'message' onto the stack
PUSH 0 ; Push param 'hWnd' onto the stack
CALL MessageBoxA ; Call (Execute/Invoke) MessageBoxA

Hmm, I kinda get it. And if the CALL is used, will it remove all the PUSH variables or will they stay in memory addresses?

---- Edit:

It doesn't work. Just saying, I'm using Flat Assembler.

Now I've fixed almost all of the bugs, however, it keeps on saying 'Undefined symbol MessageBoxA'. Just MessageBox doesn't work either.

Code:
org 100h

include 'win32ax.inc'

.code
start:
 ; in C++, the params would be the other way (hWnd, strMsg, strCaption, nType)
PUSH 0 ; Push param 'nType' onto the stack
PUSH strCaption ; Push param 'caption' onto the stack
PUSH strMsg ; Push param 'message' onto the stack
PUSH 0 ; Push param 'hWnd' onto the stack
CALL MessageBox ; Call (Execute/Invoke) MessageBoxA

strMsg db "Hello, World!", 0 ; Declare message string
strCaption db "Caption", 0 ; Declare caption string

Your code gave more errors, so I improved so most of the errors were fixed.
 
Last edited:
Hmm, I kinda get it. And if the CALL is used, will it remove all the PUSH variables or will they stay in memory addresses?

---- Edit:

It doesn't work. Just saying, I'm using Flat Assembler.

Now I've fixed almost all of the bugs, however, it keeps on saying 'Undefined symbol MessageBoxA'. Just MessageBox doesn't work either.

Code:
org 100h

include 'win32ax.inc'

.code
start:
 ; in C++, the params would be the other way (hWnd, strMsg, strCaption, nType)
PUSH 0 ; Push param 'nType' onto the stack
PUSH strCaption ; Push param 'caption' onto the stack
PUSH strMsg ; Push param 'message' onto the stack
PUSH 0 ; Push param 'hWnd' onto the stack
CALL MessageBox ; Call (Execute/Invoke) MessageBoxA

strMsg db "Hello, World!", 0 ; Declare message string
strCaption db "Caption", 0 ; Declare caption string

Your code gave more errors, so I improved so most of the errors were fixed.

I've always used the MASM compiler, lol. Also didn't include the header of it, just the body.
IIRC, this specific code should pop all of it off the stack. May want to run it through a debugger just to be sure.
I'm off work today so I'll check it out for you, and make a couple working examples.

I like the idea of some of these compilers supporting 'invoke' or '.if' / '.else' / etc., but it's always best to learn it raw first.
​Now I wanna get back into Assembly. Damn you!

I guess here's a start:
Code:
[/SIZE][/SIZE].386
.model flat, stdcall
option casemap :none


include \masm32\include\masm32rt.inc


.data?
nType       dd ?
nhWND       dd ?


.data
strMessage db "Hello World!", 0
strCaption db "Hello Caption!", 0


.code
start:


PUSH 750
PUSH 500
CALL Beep


MOV nType, 0
MOV nhWND, 0
LEA ECX, strMessage
LEA EAX, strCaption


PUSH nType
PUSH EAX
PUSH ECX
PUSH nhWND
CALL MessageBoxA
ret


end start
 
Last edited:
Hmm, I tried out to push it onto my code for FASM. It doesn't give an error but it simply doesn't show up anything.

This is the code:

Code:
org 100h

include 'win32ax.inc'

.data
strMessage db "Hello World!", 0
strCaption db "Hello Caption!", 0

.code
start:
PUSH 0
PUSH strMessage
PUSH strCaption
PUSH 0
CALL MessageBoxA
ret
.end start

I also tried without ret, doesn't work either.
 
Back