Tight_Coder_Ex 17 Posting Whiz in Training

Thank you for replying, would you also happen to know if boolean algebra is a crucial part to learning assembly?

Depends on the type of applications. There is a definite advantage when working with PLC's or Distributive Controls Systems. To be an effective programmer you must know the processor your working with first, then the language of your choice whether it be NASM, YASM, FASM, GAS, MASM etc, and then the platform be it Windows, DOS, Linux, Unix, OSX. Then you will utilize formal skills that are application specific like algebra, trigonometry, calculus and so forth.

Tight_Coder_Ex 17 Posting Whiz in Training

To become an assembly programmer understanding instruction encoding is not essential. If you were programming like the first computer http://www.imsai.net/ I had that had 8 toggle switches for instruction and 16 switches for addresses and then a button to write, this information would be critical

Fortunately, assemblers and compilers take care of this tedious business for us, so just glance through that chapter.

Tight_Coder_Ex 17 Posting Whiz in Training

Ok, I'm going to assume that it's ok to use BCD, so here is a simple snippet to get a two digit entry and leave the result in DL. Place your prompting code before here

mov    ah, 1
    int    21h
    and    al, 15
    mov    cl, 4
    shl    ax, cl
    mov    dl, al
    mov    ah, 1
    int    21h
    and    al, 15
    add    dl, al

Now move DL to somewhere else and do this again for the second value. Then we'll deal with addition and displaying the result.

You code is not WRONG. The only problem you're having is that it's not achieving the desired result. It could be fixed easily if you were allowed to use JMP or some sort of branching mechanism.

Tight_Coder_Ex 17 Posting Whiz in Training

Which processor?

Being brand new, before tackling any examples you should spend some time getting to know what your processor can actually do, especially in the case of which flags are set or reset and by which instructions.

In any event for IA32, www.masm32.com has a complete package with lots of examples and tutorials.

Tight_Coder_Ex 17 Posting Whiz in Training

If you prefer we could use BCD (Binary Coded Decimals), that would be easier yet.

Tight_Coder_Ex 17 Posting Whiz in Training

Your code is unconventional to say the least, but creative non the less. You'll also find you get unusual results if you add 54 + 93 = 7< and if you add 87 + 44 = <;

7 + 4 = 11, then add 48 to this and you get 59 which equates to ";".

So if you would like some help rebuilding this let's start with cleaning it up considerably by putting you entry parts into a subroutine and returning a binary number in AX.

Otherwise there is no viable solution to fixing what you've got

Tight_Coder_Ex 17 Posting Whiz in Training

If you insist on learning the obsolete DOS-style 16-bit code

There seems to be a lot of interest in 16 bit code in this forum , which leads me to believe there are a lot of educational institutions teaching this. My question would be WHY?

masm32.com has the whole package for 32 bit and some very good examples and tutorials.

Tight_Coder_Ex 17 Posting Whiz in Training

#1: When you move 85 55H into Fenster your result will be two ascii digits. What you've done is added 48 to 85 and then 48 to your terminator $. This might help you out

Fenster     db    85, 0, '$'

mov   dx, offset Fenster
mov   ax, Fenster
push   ax
and    ax, 15
add    ax, 48
mov   dx, al
inc     dx
pop    ax
shr     ax, 4
add    ax, 48
mov    dx, al
dec     dx

I'm not advicating this is the best way to do it, but based on your logic this is probably the closest approximation based on your code

Tight_Coder_Ex 17 Posting Whiz in Training

HANDLE hFile;

hFile = CreateFile(L"C:\\test.txt",GENERIC_READ,
FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

I thought of doing like,

1. get the file size
2. create a char* and allocate the size of file size
3. copying the entire file into a string buffer using Readfile() API,

int FSize, Actual;
char *Buffer;

FSize = GetFileSize (hFile, NULL);
Buffer = new char (FSize+1);
ReadFile (hFile, &Buffer, FSize, &Actual, NULL);

I'm pretty rusty at C++, but that is how you would read the entire file into memory.

Tight_Coder_Ex 17 Posting Whiz in Training

Thank-you, this has definitely opened the eyes amongst our development group that assembly is much more efficient for our intended project.

Tight_Coder_Ex 17 Posting Whiz in Training

In assembly I would

ProcA  enter 16, 0
          call    ProcB
          leave
          ret


ProcB  enter 16, 1
          ... code
          leave
          ret

Even if ProcA is in another file, so long as I know the order of the variables in ProcA they are visible to me in ProcB because 16 ,1 nests procedures frames one level.

So firstly, is there a pragma in VC++ or later versions that can force compiler to use ENTER instead of

push    ebp
mov    ebp, esp
add     esp, -16

and make one procedures local variables aware of another's without coercing them into globals

Tight_Coder_Ex 17 Posting Whiz in Training

Use WM_KEYDOWN as a toggle instead of an event that actually moves your character. You've probably discovered by now that your character movement corresponds to how repeat keys work. Therefore;

MoveFlag ^= 1;

Then in a timer event check if the flag is on and if so move your character.

if (MoveFlag && 1)
   .... Move Character

If you want to move in all four directions or even diagonally then just use a bit position in MoveFlag array to represent up down left right. If you use a 4 bit or 8 bit values in MoveFlag you can even change the speed you want your character to move in that direction relative to the rest.

So lets say MoveFlag represents Left Up Right Down each having a 4 bit value. Then MoveFlag = 0460H. This would move your character 4 pixels up and 6 right everytime your timer event was executed. Of course there is a lot of code that needs to be implemented to make this work, but I think you understand now how using WM_KEYDOWN, WM_KEYUP as toggles and then a timer works much better for your objective.

NOTE: I code exclusively in assembly so my C++ syntax may not be correct, but procedurally this is how I would implement.

Tight_Coder_Ex 17 Posting Whiz in Training

There are two ways of doing it, #1: Trace through the program with whichever debugger your using, #2: Emit a listing file from your compiler shows assembly with source

Tight_Coder_Ex 17 Posting Whiz in Training

in Linux you put:

mov  $1, %eax
mov  $0, %ebx
int  $0x80

The two most significant things are strip $ and % and invert operators

mov eax, 1
mov ebx, 0
int 0x80

I don't remember what the call is for Linux, but in windows to do an orderly shutdown of an application

xor eax, eax
call ExitProcess

Linux has some 18 different ways of terminating, by sending events to other applications and so on. I don't have a Linux box up and running right now, so can't give any greater detail than this.

Tight_Coder_Ex 17 Posting Whiz in Training

Which processor? In general any 8 bit unsigned addition that will cause a result greater than 255 or less than zero for subtraction will cause carry to be set, otherwise it will be reset respectively.

Tight_Coder_Ex 17 Posting Whiz in Training

Only when object files are linked to create an executable EXE, then the PE header has lots of information in it of where to start, memory allocation etc. An example would be link /entry:start /stack:0x8000 /heap:0x8000 ?.obj. In your case you didn't have to link because you've only got one file and that image is ready to go at 100H

All registers are of random values in any program on startup unless you've taken steps in preamble to set to know values before entering the main body of program

Tight_Coder_Ex 17 Posting Whiz in Training

The reason the screen clears is because AL is probably a value greater than the number of lines your displaying so it is actually scrolling that number of lines (value of AL).

Tight_Coder_Ex 17 Posting Whiz in Training

Unlike executables that have a lot more information for startup and memory allocation, your binary file always starts at the origin. So in case #2 you have to put a jump instruction ahead of scrollXLines so it will actual start where you expect

Tight_Coder_Ex 17 Posting Whiz in Training

Good catch. I missed that too. :)

Tell me about it. I don't know how many sleepless nights I've had over just this kind of error. I try to use a method of only using one radix, so in assembly I'll always use hex and C++ decimal.

Thanks for the link, but anything I do now that doesn't require XP I go to straight binary and use BIOS calls.

Tight_Coder_Ex 17 Posting Whiz in Training

You propbably want to use int 21H in line 10. What you are actually doing is calling interrupt 15H (21) instead of 21H. I can't verify that AX = 4C00 is correct because my book is for DOS 2.1

Tight_Coder_Ex 17 Posting Whiz in Training

Where am I suppose to add that code?

In your upper_case loop or byte ptr [bx], 32 I've choosen OR only because if the character was already lower case there would be no change, XOR on the other hand would change lower to upper and upper to lower thus acting like a toggle switch.

Tight_Coder_Ex 17 Posting Whiz in Training

Your assumption that NASM has the same syntax as ML (Masm) or TASM. Yes, for the most part opcodes are similar. An example would be.

ML: mov eax, Data
mov eax, offset Data

NASM: mov eax, [Data] the contents of location Data
mov eax, Data the address of data

If your going to use NASM you'll have to read the manual.

Biggest difference is NASM does not have segmented memory models and therefore ASSUMES nothing

Tight_Coder_Ex 17 Posting Whiz in Training

and after you've edited for readability, maybe post a few ideas of your own on how you would solve this problem because it is after all beyond simple.

Clue: Do the opposite of what you did to convert to uppercase!

Tight_Coder_Ex 17 Posting Whiz in Training

I'll be away for a bit so I'll give you the snippet regardless. This is written for an XP based machine, but I'm sure you'll be able to improvise.

push edi
mov al,30H ; Ascii equivalent to "0"
mov edx, 913387 ; You can make this any value
std ; set EDI to auto decrement
mov edi, 401087
.D0 mov al, dl
and al, 15 ; strip bits 7 - 4
or al, 30H
stosb
shr edx, 4 ; shift next digit
jnz .D0
mov eax, edi
inc eax
pop edi
cld
pop edi

This method leaves base address of string in EAX, but you can put it anywhere.

This only works if you are displaying decimal digits. You'll have to modify loop if you want hex in order to display A - F.

Tight_Coder_Ex 17 Posting Whiz in Training

If you really get stuck I can post a short snippet on the example Ancient Dragon gave you. Just to clarify you are using NASM on an intel based machine that uses Linux. The reason I ask is that I'm assuming in your first post rax actually means eax.

Tight_Coder_Ex 17 Posting Whiz in Training

If your application is pure assembly then the way AncientDragon explained it is the only way unless you use BCD or want to display result in decimal. A lot of applications I do are for windows therefore I use wsprintf a function of kernel32.lib and then one of the parameters such as %d or decimal or %X for hex will do the conversion for me

Tight_Coder_Ex 17 Posting Whiz in Training

I use ML & NASM only because they both use intel's syntax. That being said though, if your compiler is doing everything you want it do then its probably a good compiler. In my case the only advantage ML has over NASM is that emits adequate information for Olleybug so I can view my source in the debugger. The level of difficulty in programming anything depends on your level of knowledge of the device or environment. Case in point, 9 years ago I found windows programming in assembly or even "C" & "C++" very difficult because I was just learning the API's. Now I find it relatively easy

Tight_Coder_Ex 17 Posting Whiz in Training

The problem probably is at Speed Gonzales3456. There is no space between es and 3456, so afterwards everything is out of sync by one field.

You last post wasn't visible to me until I posted this one

Tight_Coder_Ex 17 Posting Whiz in Training

Probably the simplest thing to do is pull the key off and see what is making it keep continuous contact.&nbsp; Usually it's pretty easy to see if there's something broken or foreign material not allowing to travel freely.&nbsp; Most often I've found a simple cleaning solves the problem<br>

Tight_Coder_Ex 17 Posting Whiz in Training

Elaborate specifically what string you want to send to which application and then I might get a better understanding what you mean by shell code.

Tight_Coder_Ex 17 Posting Whiz in Training

You've got the idea. The only thing your application has to do is get the Device Context of the window you want the text to appear on and then dependant upon the API function you want to use, push the appropriate parameters on the stack and call the function.

Like the example I gave you in the previous message, DrawText requires 5 parameters.

Post the code your going to use in its entirety and I should be able to help you further from there

Tight_Coder_Ex 17 Posting Whiz in Training

As you elude to WinXP, I'll assume you are doing a windows application and as such you must include kernel32.lib and call one of the text emitting functions DrawText, TextOut or ExTextOut. For example DrawText requires 5 parameters as follows

1. Your programs window device context
2. Long pointer to string (in your case Command)
3. Length of string
4. Pointer to bounding rectangle (see Rect Structure)
5. Flags, how you want the text to be displayed within defined rectangle.

Tight_Coder_Ex 17 Posting Whiz in Training

I've never used TASM, but maybe this might help steer you in the right direction.

In NASM I must compile "NASMW -fwin32 sourcefile". Note -fwin32, this tells the compiler which platform I intend to compile application for.

then "link /entry:Main /machine:ix86 ......", this tell the linker the entry point and what type of machine I intend on running it on.

So check you compiler and linker options to make sure you are using the correct ones so your PE header is created properly for the windows platform.

Tight_Coder_Ex 17 Posting Whiz in Training

What is the underlying operating system, or are you using BIOS calls.

In any event, EAX won't work because especially in the case of ASCII only an 8 bit value is returned and you are comparing a 32 bit value and may not know at any given time what the value of bits 31 - 8 are. Comparing cmp al,'q', should work except where caps lock may be on then you would have to compare against 'Q'. The method I usually use is to implement a case insensitive comparison where I'll convert all characters in AL to upper or lower case.

mov al, [Character]
and al, 0x5f
cmp al,'Q'
jz Done
Tight_Coder_Ex 17 Posting Whiz in Training

if the program TEST.ASM has been designed as an EXE program , can the program TEST.OBJ be executed successfully
No. Object files are simply a binary image of what the compiler determined is the most appropriate interpretation of source. You must then take that/those object files and link them together. For example, I use NASM and it would look like this.

c:\>nasmw -fwin32 Test.asm
c:\>link /entry:Main /subsystem:console /machine:ix86 Test kernel32.lib user32.lib gdi32.lib

So the compiler generates Test.obj from Test.asm and the linker generates Test.exe from Test.obj.

What is the meaning of the following directive ?
PAGE 55,132
If you direct the compiler to emit an assembly listing it will put 55 lines/page and each line will be a maximum of 132 columns

In a program consisting of seperately compiled modules what is the assembler's name for a reference to a label outside the current module?

In the case of NASM, where I declare the variable I have to qualify it with
global

global ScrBuff
ScrBuff db 0

then in the other file where I want to access

extern ScrBuff

if this programs code segment were loaded by DOS at absolute address 18400h , what would be the absolute addresses of the data and stack segments ?

Generally a map files address can be treated as offsets. So all you do is add the start to your destination. I would recommend though you don't use map information as a form of coding …

Tight_Coder_Ex 17 Posting Whiz in Training
case WM_CREATE:
GetClientRect (hWnd, &Rc);
InflateRect (&Rc, -10, -10);
 
StatusArea = DisplayArea = Rc;
StatusArea.top = StatusArea.bottom - 32;
DisplayArea.top += 32;
DisplayArea.bottom = StatusArea.top - 10;
 
EditWnd = CreateWindowEx (WS_EX_STATICEDGE | WS_EX_CLIENTEDGE, "EDITCTL", NULL,
				WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL,
				Rc.left, Rc.top, Rc.right - 
				Rc.left, 22,
				hWnd, (HMENU) IDC_EDIT, hInst, NULL);
 
SendMessage (EditWnd, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG (8, 8));
SendMessage (EditWnd, WM_SETFONT,
		 int (GetStockObject (DEFAULT_GUI_FONT)),
		 MAKELPARAM (false, 0));
DisplayFont = [b]CreateFont (-12, 0, 0, 0, FW_DONTCARE, false, false, false, OEM_CHARSET,[/b]
[b]				OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,[/b]
[b]				DEFAULT_PITCH | FF_DONTCARE, "Arial");[/b]
SetFocus (EditWnd);
break;

and then to use

HDC Dc = GetDC (MainWnd);
[b]SelectObject (Dc, DisplayFont);[/b]
SetBkMode (Dc, TRANSPARENT);

There is a utility provided with VC++ 6.0 called FontView. It allows you to visually see what all the setting will do and then you need just duplicate them in CreateFont

Tight_Coder_Ex 17 Posting Whiz in Training

CreateFont as 14 parameters that need be passed to it, and it will provide you with everything you need to create the font you need.

Tight_Coder_Ex 17 Posting Whiz in Training

There are subtle differences between these two methods, so you may want to check out in detail which one suites your purposes. In any case either will work.

SendMessage (hWnd, WM_SETTEXT, 0, char *);

or

SetWindowText (hWnd, char *)
Tight_Coder_Ex 17 Posting Whiz in Training

Put all your printf() back in, take out one at a time and then you'll know exactly where the problem is.

Tight_Coder_Ex 17 Posting Whiz in Training
void delspace (char *Str)
{
int Pntr = 0;
int Dest = 0;
 
while (Str [Pntr])
{
if (Str [Pntr] != ' ')
	Str [Dest++] = Str [Pntr];
Pntr++;
}
 
Str [Pntr] = 0;
}

Think in terms of how you would have to do something manually and then coding it usually straight forward.

Tight_Coder_Ex 17 Posting Whiz in Training

When you created this project you may have inadvertantly selected of the 15 choices the wrong type. In your case Win32 Console Application would have been the one you wanted. There are also several other settings that could have been corrupted, so the simplest thing to do is create a new console project, attach your headers and source files and re-build.

Tight_Coder_Ex 17 Posting Whiz in Training

XP/NT/2000 have restructured the way DOS works, and many people have complained too that after installing SP2, QBasic and other programs won't work. Virus writers have depended extensively in the past using DOS and more particularly dropping into BIOS to circumvent kernel code.

Tight_Coder_Ex 17 Posting Whiz in Training

Some pretty interesting stuff in this thread. I though I might step right out of the box and do something that can be put into the MBR (Master Boot Record) and copied to a floppy. I choose to provide the listing like this incase someone wanted to try it out without using an assembler. If you alread have a bootable floppy disk it would work just find.

First 3 bytes are memory address and the rest are opcodes for 386 or better

000 FA				 cli
001 FC				 cld
002 B8C007			 mov ax, 0x7c0
005 8ED8				 mov ds, ax
007 8EC0				 mov es, ax ; Setup segments to boot area
009 8ED0				 mov ss, ax
00B BCFFFF			 mov sp, 0xffff
00E FB					 sti
 
00F BD[2500]			 mov bp, Msg
012 B92000				mov cx, MsgLen
015 BA100A			 mov dx, 0x0a10 ; DH = Row (10), DL = Column (16)
018 B304				 mov bl, 4 ; Red
01A B80113			 mov ax, 0x1301 ; AH = Write String, AL = chars only
01D CD10				 int 0x10 ; Video serice call
 
01F 31C0				 xor ax, ax
021 CD16				 int 0x16 ; Wait for operators input
023 CD19				 int 0x19 ; Re-boot
 
025 48454C4C4F20574F52- Msg db 'HELLO WORLD', 13, 10, 'Any key to continue'
02E 4C440D0A416E79206B-
037 657920746F20636F6E-
040 74696E7565		 
						 MsgLen equ $ - Msg
 
045 90<rept>			times 510 - ($-$$) nop
1FE 55AA				db 0x55, 0xaa

and the formatting is what it is. Cutting and pasting between code tags is probably the most cumbersome thing I've ever used.

Tight_Coder_Ex 17 Posting Whiz in Training

Thanks Dave, just what I was looking for and much more!

Tight_Coder_Ex 17 Posting Whiz in Training

sorry but cant you use setwidth function ? Or something similar?

That accomplishes the formatting I want, but still doesn't solve the problem of assigning it to a string variable.

Tight_Coder_Ex 17 Posting Whiz in Training

I'd like to read a floating point value cin >> Value where Value is declared as a double and then output it to a string justified to two decimal places. I understand how to do it using a temporary file, but I'd like to avoid that method and sprintf() if possible

Tight_Coder_Ex 17 Posting Whiz in Training

Ok as promised here is my modification based on your algorithym

# include <iostream>
# include <iomanip>
# include <string>
using namespace std;
int main()
{
int Quantity, Disc;
double Cost, Discount, SalesTax;
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
cout << "\n\nThe Acme Software Company\nby Kristen Ngoc, Nguyen"; //PROGRAM AUTHOR
do
{
cout << "\n\nPlease enter the units you want to purchase: "; //INPUT DATA FOR UNITS
cin >> Quantity;
if (Quantity == 0)
	break;
Cost = 109.0 * Quantity;
if (Quantity < 10)
	Disc = 0;
else
	if (Quantity < 20)
	 Disc = 20;
	else
	 if (Quantity < 50)
	 Disc = 30;
	 else
	 if (Quantity < 100)
	 Disc = 40;
	 else
	 Disc = 50;
 
cout << fixed << showpoint << setw (20);
cout <<"\nSales Results\n";
cout <<"- - - - - - - - - - \n";
cout << setw(20) << "Cost" << setw(25) << Cost << endl; 
Discount = Cost * (double (Disc) / 100.0);
cout << setw(20) << "Less" << setw(25) << Discount << " " << Disc << "%" << endl;
cout << setw(20) << "Total Cost" << setw (25) << Cost - Discount << endl;
SalesTax = (Cost - Discount) * .0775;
cout << setw(20) << "7.75% Sales Tax" << setw (25) << SalesTax << endl;
cout << setw (45) << "_________________" << endl;
cout << setw(20) << "Total" << setw (25) << Cost - Discount + SalesTax << endl;
} while (1);
return 0;
}

Basically all I did with your code is eliminate redundancy. Only …

Tight_Coder_Ex 17 Posting Whiz in Training

In all cases remove quotes around bolded section

cout <<"\n" << setw(20) << "Adjust Amount $" << [b]"AdjustAmount"[/b] << endl;

Declare DiscountRate in your application and set its value inside each conditional

cout <<"\n" << setw(20) << "Discount rate " << DiscountRate << endl;

As you've gotten it 95% right, I will post a modified version of this app that you can use as a reference. Don't use it as your assignment or your instructor may get you to explain why you did it that way.

Tight_Coder_Ex 17 Posting Whiz in Training

I have finish but I couldn't calculate and it not work

Show us what you've got done so far, so we know what to tell you to correct.

Tight_Coder_Ex 17 Posting Whiz in Training

In your ok button click event you have to read the contents of path. Not having used borland I'm not sure how its done, but using a WIN32 API it would be GetWindowText (hWnd, char *, int size); or in MFC path.m_text where m_text is the variable assigned to object path. So you don't need the variable path in your ok button click event.

So all you have to do is find out how to read the text from path edit control and then use save << ??? whatever that method is.