News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Converting 16bit to 32bit(str_remove program)

Started by Syre Lancaster, October 05, 2013, 03:09:43 AM

Previous topic - Next topic

Syre Lancaster

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

dedndave

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

dedndave

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

dedndave

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

Syre Lancaster

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 >.>

dedndave

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/
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

Syre Lancaster

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 ^.^

dedndave

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:

jj2007

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.

japheth

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.

hutch--

> The Win32 ABI is a M$ invention - so M$ just followed their own ABI.

Intel would disagree with you.

dedndave

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

japheth

Ok, I take my "statement" back - before it causes major turbulence  :icon_mrgreen:. It was anyway just a "by-the-way"-remark.

dedndave

i'm not sure about the win32 ABI
but, intel has an "x32" ABI definition - not the same thing, though

jj2007

Debunking x32 myths - very biased imo, the idea as such is a good one, and most benchmarks do give an advantage over x64.