The MASM Forum

Miscellaneous => Irvine Book Questions. => Topic started by: Syre Lancaster on October 05, 2013, 03:09:43 AM

Title: Converting 16bit to 32bit(str_remove program)
Post by: Syre Lancaster on October 05, 2013, 03:09:43 AM
Hey again guys, I have been working on my exercises and I'm trying to convert a program from 16 bit to 32 bit. I tried running the original program and it didn't work for some odd reason or another so I've already flipped the registers and such to 32 bit but it still doesn't run correctly.

I think the answer here is fairly simple, it is just alluding my noobish mind.

Errors:
Error   1   error A2111: conflicting parameter definition   C:\Irvine\Examples\Project_sample\Problem 20.asm   52   1   ASM_Project
Error   2   error A2004: symbol type conflict   C:\Irvine\Examples\Project_sample\Problem 20.asm   10   1   ASM_Project


Code:

INCLUDE Irvine32.inc
;The purpose of this program is to parse a string, locate the offending segment "xxxx" and remove it from the string.

.data
target BYTE "abcxxxxdefghijklmop",0
start_add DWORD 3
no_chars  DWORD 4

.code
main:
mov eax,@data
mov ds,eax
mov es,eax
mov edi,OFFSET target
push edi
mov eax,start_add
push eax
mov eax,no_chars
push eax
call str_remove
mov byte ptr[edi],'$'
mov ah,09h
mov edx,OFFSET target
int 21h
mov ah,4ch
int 21h


;----------------------------------------
str_remove PROC
;----------------------------------------
push ebp
mov ebp,esp
cld
mov ecx,[ebp+6]

call str_length
mov ecx,eax
sub ecx,[ebp+6]
sub ecx,[ebp+8]

mov edi,[ebp+10]
add edi,[ebp+8]
mov esi,edi
add esi,[ebp+6]
rep movsb
pop ebp
ret 8

str_remove ENDP

;----------------------------------------
str_length PROC
;input edi offset of the string
;output:ad
;----------------------------------------
push edi
mov eax,0
L1: cmp BYTE ptr [edi],0
je L2
inc edi
inc eax
jmp L1
L2:
pop edi
ret
str_length ENDP
END main
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 05, 2013, 03:28:12 AM
the first problem is
mov eax,@data
mov ds,eax
mov es,eax

32-bit windows uses a "flat" memory model
i.e., one big segment for everything
just remove those lines of code

the next problem is
mov byte ptr[edi],'$'
mov ah,09h
mov edx,OFFSET target
int 21h
mov ah,4ch
int 21h

use the WriteString function that is defined in Irvine32 to display strings
and, the "exit" macro or ExitProcess to terminate the program
INT's are essentially unusable in 32-bit apps

finally, the one that is spitting out errors, seems to be the use of "main"
maybe Irvine uses that symbol elsewhere
just change it to something a little different
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 05, 2013, 03:37:23 AM
there are a couple issues, here
str_remove PROC
;----------------------------------------
push ebp
mov ebp,esp
cld
mov ecx,[ebp+6]

call str_length
mov ecx,eax
sub ecx,[ebp+6]
sub ecx,[ebp+8]

mov edi,[ebp+10]
add edi,[ebp+8]
mov esi,edi
add esi,[ebp+6]
rep movsb
pop ebp
ret 8

str_remove ENDP


[EBP+6] [EBP+10] ????
check your math on those   :biggrin:

the assembler will take care of the stack frame for you, if you use it to fullest extent
MyFunc PROC Argument1:DWORD,Argument2:DWORD

    mov     edi,Argument1
    mov     ecx,Argument2
;
; more code
;
    ret

MyFunc ENDP

if you provide a PROTOtype near the beginning of source (usually right after the INCLUDE's)
MyFunc PROTO :DWORD,:DWORD
you can call the function with the arguments by using INVOKE
    INVOKE  MyFunc,Arg1,Arg2

the assembler generates a prologue at the beginning of the routine to set up the stack frame
and, anywhere a RET is encountered, it will generate an epilogue to clean it up
also, it will clean up the arguments from the stack (because we are using StdCall)
so - in my example, it will use RET 8 because there are 2 dword parms to remove
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 05, 2013, 03:45:47 AM
one final note....

Kip does not follow the intel ABI, MS does   :P

EAX, ECX, EDX are volatile across function calls
EAX is often used to return a result or status

EBX, ESI, EDI, EBP are preserved across function calls

the direction flag should be cleared when calling an API function
so - you can assume it is cleared, unless you have set it
and - if you set it, you should clear it when done

these rules apply to windows function calls
but, we generally try to follow the same set of rules when we write functions

when Kip and Randy wrote their 32-bit books, they more-or-less "upgraded" their old 16-bit routines
so - they still pass values in registers and, in some cases, do not follow the ABI
it would be nice if they would update their books and libraries   :t
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: Syre Lancaster on October 05, 2013, 03:58:21 AM
So the guy who wrote the code had no idea what he was doing. Yeah, I figured as much. It looked all wrong to me when I was looking at it. For the last few weeks they have had instructional videos on the website that kinda give you a starting point, but this week (finals week) they are just like "Oh...figure it out for yourselves"

Alas, examples found on google search are less than accurate sometimes >.>
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 05, 2013, 04:03:58 AM
Quote from: Syre Lancaster on October 05, 2013, 03:58:21 AM
So the guy who wrote the code had no idea what he was doing.

i hope you aren't refering to Kip - lol
we like Kip and Randy - they are actually good authors that have helped many get started
they just need to move away from the old 16-bit ways, is all

as for examples....
if you install the masm32 package
http://masm32.com/ (http://masm32.com/)
you will find tutorials, help files, and many examples
also - most of us use that set of libraries - so you are likely to get more help in the forum

use the book to understand individual instructions
use the masm32 libraries and examples to help write code   :t
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: Syre Lancaster on October 05, 2013, 04:06:44 AM
No, the example I was referring to was found online, unaffiliated with Kip Irvine. Thanks for that resource I may be able to get somewhere with this now ^.^
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 05, 2013, 04:13:24 AM
one more note - again

for every function in the Irvine32 library, there is probably an analogous function in the masm32 library

Irvine32: WriteString
you pass it arguments in registers, and it displays a string

Masm32: StdOut
you use INVOKE, passing the address of the null-terminated string on the stack, and it displays a string
there is also a "print" macro that can simplify some of your code

Irvine32: StrLength
you pass it arguments in registers, and it returns the length

Masm32: StrLen
you use INVOKE, passing the address of the null-terminated string on the stack, and it returns the length
there is also a "len" macro - lol
although, you don't have to use this function as often because StdOut gets the length for you   :biggrin:
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: jj2007 on October 05, 2013, 04:31:54 AM
Quote from: dedndave on October 05, 2013, 03:45:47 AMwhen Kip and Randy wrote their 32-bit books, they more-or-less "upgraded" their old 16-bit routines

Indeed. You can "upgrade" 16-bit code, but often it makes more sense to ask "what should the code do?", and then re-write it from scratch. 32-bit code is a lot more powerful, because you have over 10,000 Windows API functions, plus the Masm32 library. \Masm32\help\hlhelp.chm is a good read in this respect - see e.g. Macro Categories/String macros/Find$ for your xxxx problem.
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: japheth on October 05, 2013, 05:04:58 PM
Quote from: Syre Lancaster on October 05, 2013, 03:58:21 AM
So the guy who wrote the code had no idea what he was doing.

The code most likely was assumed to run with the help of a DOS extender, in a 32-bit segmented memory model.

In this case the "guy" knew exactly what he was doing, but perhaps just forgot to mention how the sample was supposed to be assembled and linked - or you just missed this information bit.

> Kip does not follow the intel ABI, MS does

The Win32 ABI is a M$ invention - so M$ just followed their own ABI.
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: hutch-- on October 05, 2013, 05:15:10 PM
> The Win32 ABI is a M$ invention - so M$ just followed their own ABI.

Intel would disagree with you.
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 05, 2013, 06:49:39 PM
intel does define some ABI's - i know that much - lol

but - does it really matter to the beginner in this sub-forum ?
no - the point is - the ABI is followed by MS, and much of our code

it's not exactly followed by Kip and Randy, with regard to their libraries and examples
something they do that is really old-school is to pass arguments in register,
while the rest of us pass arguments on the stack
i know about fast call, so don't go there - again, not a beginner subject

for a beginner, it's confusing to see one thing in the book, and something entirely different elsewhere
worse, many university professors know less than the students - lol
they select a book (likely from an approved list) and tell the students to buy it

many of these professors are math teachers or come from some other discipline - lol
in the best cases, they are C programmers, themselves
it's rare to find one that is actually fluent in assembler
they don't understand the difference between 16-bit, 32-bit extensions, and win32

assembly language (for a beginner) is hard enough without all the waxing and waning
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: japheth on October 05, 2013, 07:44:41 PM
Ok, I take my "statement" back - before it causes major turbulence  :icon_mrgreen:. It was anyway just a "by-the-way"-remark.
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 05, 2013, 07:59:44 PM
i'm not sure about the win32 ABI
but, intel has an "x32" ABI definition - not the same thing, though
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: jj2007 on October 05, 2013, 08:09:36 PM
Debunking x32 myths (https://blog.flameeyes.eu/2012/06/debunking-x32-myths) - very biased imo, the idea as such is a good one, and most benchmarks do give an advantage over x64.
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: nidud on October 05, 2013, 08:57:23 PM
deleted
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: sinsi on October 05, 2013, 09:11:10 PM
The ABI is the mechanics of doing an API call, in Windows it filters down to an INT, same for Linux, same for DOS.
Quote from: japhethThe Win32 ABI is a M$ invention - so M$ just followed their own ABI.
In this instance japheth is correct. The OS defines the ABI.

ps, do we really need the M$ crap? It gets tiresome...
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: nidud on October 05, 2013, 09:31:20 PM
deleted
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: Paulo on October 05, 2013, 11:40:58 PM
Quote from: sinsi on October 05, 2013, 09:11:10 PM
The ABI is the mechanics of doing an API call, in Windows it filters down to an INT, same for Linux, same for DOS.

I'm intrigued, I know that in 16 bit DOS apps we have BIOS and DOS INTs and in Linux INT 80h is used,
but how does this apply to Win32?
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: sinsi on October 05, 2013, 11:59:37 PM
To make a ring3 to ring0 call you would use an interrupt gate, the NT calls boil down to loading the registers and an INT (2D maybe?).
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 06, 2013, 12:04:52 AM
for the most part, however, we call windows functions by pushing values on the stack and using CALL
the assembler has an internal macro named INVOKE to do this
    INVOKE  WriteFile,hFile,offset buffer,nNumberOfBytes,offset NumberOfBytesWritten,NULL

this is how WriteFile is defined for C
BOOL WINAPI WriteFile(
  _In_         HANDLE hFile,
  _In_         LPCVOID lpBuffer,
  _In_         DWORD nNumberOfBytesToWrite,
  _Out_opt_    LPDWORD lpNumberOfBytesWritten,
  _Inout_opt_  LPOVERLAPPED lpOverlapped
);

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747%28v=vs.85%29.aspx)

there are some 10 to 100 thousand such functions
not as easy to memorize as the DOS interrupts, but much more powerful   :P
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: Paulo on October 06, 2013, 12:09:21 AM
@sinsi

OK INT3h is used for debugging and INT 2dh mostly for drivers?
Are there others that are used for a "normal" user mode app running at Ring3
or as dedndave writes we simply push onto the stack and call the required API?

I have used INT3h many times and am comfortable with the Windows API, but never heard of other INTs
hence the reason for asking.
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 06, 2013, 12:16:30 AM
the win32 ABI becomes more evident when you start writing GUI applications
the OS sends messages to your window by calling a WndProc function that is defined by you
you must obey the rules of the ABI when handling these messages
so - if you want to call a function from WndProc, that function should obey the rules
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: Paulo on October 06, 2013, 12:18:31 AM
OK but how does the ABI relate to INTs and which ones?
That is the part I don't understand.
Are you saying that Windows messages are INT based?
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 06, 2013, 12:20:44 AM
well - in 16-bit DOS - there was a different ABI - not sure it was ever called that
you passed values in registers and, in some cases, certain registers were preserved
then, you call the function with INT

the use of INT may be internal to some win32 functions
truthfully, i don't know how much INT's are used by the OS
probably used more for "housekeeping" operations than anything

for win32, you can more-or-less forget about INT's
you will use INT 3 for debugging
but, unless you are writing drivers, that's about all you'll see of them
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: Paulo on October 06, 2013, 12:28:31 AM
Still not clear on how INTs relate to Win32.

In DOS we do like so:



        MOV AH,9
        INT 21H
        RET


and in Linux (32 bit CLI app):


section     .text
global      _start                              ;must be declared for linker (ld)

_start:                                         ;tell linker entry point

mov     edx,len                             ;message length
mov     ecx,msg                             ;message to write
mov     ebx,1                               ;file descriptor (stdout)
mov     eax,4                               ;system call number (sys_write)
int     0x80                                ;call kernel

mov     eax,1                               ;system call number (sys_exit)
int     0x80                                ;call kernel

section     .data

msg     db  'Hello, world!',0xa                 ;our string
len     equ $ - msg                             ;length of our string


But in Win32, I have only ever seen the use of the API, pushing onto the stack and calling.
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: sinsi on October 06, 2013, 12:29:39 AM
Eventually you need to get to ring0, this is the true windows kernel e.g. your exe calls a function in kernel32.dll which calls a function in ntdll.dll which calls a function in...until you get to the lowest user level. then it's load the regs and perform an int.
Ring3 to ring0 is expensive as far as cycles go so a lot of user-type information is cached, it stays in userland.
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: Paulo on October 06, 2013, 12:35:52 AM
@dedndave

OK got it, you updated your previous post after I wrote mine.

@sinsi

I understand that certain functions require Ring0, which normally use NTDLL but other then that?

Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: GoneFishing on October 06, 2013, 12:43:10 AM
...
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 06, 2013, 12:52:23 AM
sorry about that, Paulo
i am an old fart - seems like everything is an afterthought - lol
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: Paulo on October 06, 2013, 01:04:04 AM
Quote from: dedndave on October 06, 2013, 12:52:23 AM
sorry about that, Paulo
i am an old fart - seems like everything is an afterthought - lol

:t I know the feeling well.  :biggrin:

@vertograd

I think software INTs under Win32 are emulated in NTVM when one runs 16 Bit code? is that correct?
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: GoneFishing on October 06, 2013, 01:12:51 AM
...
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: dedndave on October 06, 2013, 03:49:21 AM
that's correct
you are running in protected mode
and - INT's are allowed in ring 0

NTVDM emulates them so that most old 16-bit code can work in a protected environment
(New Technology Virtual Dos Machine)
Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: MichaelW on October 06, 2013, 06:08:32 AM
Quote from: dedndave on October 06, 2013, 03:49:21 AM
NTVDM emulates them so that most old 16-bit code can work in a protected environment

And the same for 32-bit DOS apps.

Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: japheth on October 06, 2013, 06:31:37 AM
Quote from: Paulo on October 06, 2013, 01:04:04 AM
I think software INTs under Win32 are emulated in NTVM when one runs 16 Bit code? is that correct?

Not necessarily. It's always true for 80386 and 80486 cpus, but beginning with the Pentium, there exists a flag in CR4, called VME. In short, this flag, in conjunction with a bit-table in the current TSS, allows to avoid leaving V86-mode if a software INT is executed.

See for example http://www.rcollins.org/articles/vme1/VME_Overview.html (http://www.rcollins.org/articles/vme1/VME_Overview.html).

Hardware interrupts and exceptions are not affected by VME, and since  the OS does also not allow I/O-port access in ring 3, there is no security problem.


Title: Re: Converting 16bit to 32bit(str_remove program)
Post by: Paulo on October 06, 2013, 06:39:33 AM
WOW.

(http://s22.postimg.org/5k3y0oy69/vme.jpg)