Simple 8086 Assembly String Array and Printing - arrays

I have to write a program for my Assembly class that allows the user to enter his/her full name and the program then utilizes and array to store the characters and print them in the following order: "LastName", "Middle"(Optional and can have more than one middle name" "First". I have gotten my program to almost do this except it prints out a '$' at the start of the Last name. I have tried incrementing the index (bx) but then it gives me a garbled output. I am fairly new to assembly so please bear with me. I am thinking my macros might be interfering with my output when I increment the index. Also please bear with my formatting. I can never transfer code correctly. Thanks in Advance!
Here is my code:
;This Program Reads in a user's full name and prints out the results in the format
'Lastname', 'Middle'(Optional), First using an array.
include pcmac.inc
.MODEL SMALL
.586 ;Allows Pentium instructions. Must come after .MODEL
.STACK 100h
.DATA
MAXBUF EQU 100
GetBuf DB MAXBUF
GetCnt DB ?
CharStr DB MAXBUF DUP (?)
Message DB 'Enter your full name',10,13,'$'
Message2 DB 'Here is your name in the correct format', 10,13,'$'
Count DB 0
.CODE
Array PROC
_Begin
_PutStr Message
_GetStr GetBuf
mov bl, GetCnt
sub bh,bh
FindLast:
cmp [CharStr+bx],32
je SeperateLast
dec bx
inc Count ;Counter to record how long the lastname is
jmp FindLast
SeperateLast:
mov [CharStr+bx],'$'
_PutStr Message2
jmp Printlast
FirstName:
_PutCh ',',32 ;Add comma and space for readability
_PutStr CharStr ;Print up to the inputted dollar sign
_PutCh 10,13
jmp Done
Printlast:
cmp Count,0
je FirstName
_PutCh[CharStr+bx] ;Print Last Name Character by Character
inc bx
dec Count
jmp Printlast
Done:
_Exit 0
Array ENDP
END Array

From what I can see in your code, you seem to be properly finding the last name. Since the space before the last name represents the end of the First and Middle name it makes sense to replace the space with the $ sign just before the last name. Since BX is the offset of the dollar sign you just put in, you should increment BX by one to skip over it. You then need to decrement the Count variable by 1 as well.
This code:
mov [CharStr+bx],'$'
_PutStr Message2
jmp Printlast
Should probably be something like:
mov [CharStr+bx],'$'
inc bx
dec Count
_PutStr Message2
jmp Printlast

Related

What is the beginning and the end of this disassembled array?

In a disassembled dll (by IDA), I reached an array, which is commented as an array of int (but it may be of byte):
.rdata:000000018003CC00 ; int boxA[264]
.rdata:000000018003CC00 boxA dd 0 ; DATA XREF: BlockPrepXOR+5FC↑r
.rdata:000000018003CC04 db 0Eh
.rdata:000000018003CC05 db 0Bh
.rdata:000000018003CC06 db 0Dh
.rdata:000000018003CC07 db 9
.rdata:000000018003CC08 db 1Ch
.rdata:000000018003CC09 db 16h
.rdata:000000018003CC0A db 1Ah
.rdata:000000018003CC0B db 12h
.rdata:000000018003CC0C db 12h
.rdata:000000018003CC0D db 1Dh
.rdata:000000018003CC0E db 17h
.rdata:000000018003CC0F db 1Bh
Can I interpret the data as
{000000h, E0B0D09h, 1C161A12h, ..} or
{0, 90D0B0Eh, 121A161Ch, ...} or
{00h,00h,00h,00h, 0Eh, 0Bh, ..} ?
From the comment (from IDA), can you confirm that the array ends at CC00h + 253*4 = D01Fh ? I have another array starting at D020h:
.rdata:000000018003D01D db 0F9h ; ù
.rdata:000000018003D01E db 0A2h ; ¢
.rdata:000000018003D01F db 3Fh ; ?
.rdata:000000018003D020 array4_1248 db 1 ; DATA XREF: BlockPrepXOR+39A↑o
.rdata:000000018003D021 db 2
.rdata:000000018003D022 db 4
.rdata:000000018003D023 db 8
That's just the AES decryption's T8 matrix as described in this paper.
You can easily identify it by looking for the DWORDs values on Google (e.g. this is one of the results).
So that's just data for an AES decryption function.
Note also that the interpretation of a sequence of bytes as a sequence of multi-byte data (WORDs, DWORDs, QWORDs, and so on) depends on the architecture.
For x86, only the little-endian interpretation is correct (this is your case 2) but data may undergo arbitrary manipulations (e.g. it can be bswapped) so, when looking on Google, always use both the little and the big-endian versions of the data.
It's also worth noting that IDA can interpret the bytes as DWORDs (type d twice or use the context menù), showing the correct value based on the architecture of disassembled binary.

Autohotkey variable expressions for pseudo-arrays - Convert String to Number?

This question was answered at the bottom of this post.
I have looked at 6 different web pages from the AHK forums asking this question, and another one on SO here:
String to Number using autohotkey
...but none of them are working for me. I'm just trying to subtract a number from a string that has been grabbed from the StringSplit function. This is my code:
; Assign entry price variable.
StringSplit, prices, Window1Text, `n
MsgBox, Your entry price is %prices32%.
; Assign Stop Loss variable
SLPrice := %prices32% -= 0.10
MsgBox, Your SLPrice is %SLPrice%.
I receive the error "The following variable name contains an illegal character" on the line "SLPrice := %prices32% -= 0.10", so then I try:
; Assign entry price variable.
StringSplit, prices, Window1Text, `n
MsgBox, Your entry price is %prices32%.
; Assign Stop Loss variable
SLPrice = %prices32% - 0.10
MsgBox, Your SLPrice is %SLPrice%.
...to which I get the output:
Your SLPrice is 7.450 - 0.10
So it just displays the formula as a text string, it doesn't actually do the calculation.
Thoughts? Thanks!
UPDATE
To continue working out this solution, here is my full code up to the part I'm having an issue with, along with screenshots of what's happening:
; Get the latest window text to parse values from it
WinGetText, Window1Text, ahk_class WindowsForms10.Window.8.app.0.f96fc5_r9_ad1
MsgBox, The text is: %Window1Text% ; Displays the window get text values
Sleep, 5
; Assign entry price variable.
StringSplit, prices, Window1Text, `n
MsgBox, Your entry price is %prices32%.
; Assign Stop Loss variable
SLPrice := prices32 - 0.10
MsgBox, Your SLPrice is %SLPrice%.
ANSWER
Thanks to the contributor below, we discovered that there was a "." from the first MsgBox messing up the SLPrice variable, so we updated the SLPrice variable to read:
SLPrice := SubStr(Trim(prices32), 1, 5) - 0.10 ; to pull the left 5 characters
Thanks!
You are on the right track. But, per my comment, note := implies expressions including variable expressions (hence no surrounding %'s):
; Assign entry price variable.
StringSplit, prices, Window1Text, `n
MsgBox, Your entry price is %prices32%.
; Assign Stop Loss variable
; Note, the 32 line also includes non printing characters
; so must be trimmed and then we take the left 5 characters
SLPrice := SubStr(Trim(prices32), 1, 5) - 0.10
MsgBox, Your SLPrice is %SLPrice%.
Should do it . . .
And note, using something := %myvariable% implies reading the contents of a variable named myvariable and using those contents as the variable name. So if myvariable is "test", you are really saying something := test (where something ends up being equal to the contents of the test variable).
Hth,
EDIT per below, here is a working example (BUT PER LATTER COMMENT, SEE BELOW, TOO):
Window1Text =
(
25
26
27
28
)
; Assign entry price variable.
StringSplit, prices, Window1Text, `n
MsgBox, Your entry price is %prices2%. ; using only 2nd line (26)
; Assign Stop Loss variable
SLPrice := prices2 - 0.10 ; again, changed to 2nd line
MsgBox, Your SLPrice is %SLPrice%. ; 25.900000
clipboard := SLPrice
HTH,
FURTHER EDIT: Because this is really cool and illustrates the several concepts as to how they relate to pseudo array variable expressions:
Window1Text =
(
25
26
27
28
)
; Assign entry price variable.
StringSplit, prices, Window1Text, `n ; (prices0 is the number of entries)
InputBox, num,, % "Pick an array number from 1 to " prices0 ; get the array number
; note the variable expression includes the num variable contents
MsgBox, % "Your entry price is " Trim(prices%num%) "." ; depends on array number
; Assign Stop Loss variable
SLPrice := Trim(prices%num%) - 0.10 ; uses the array number value
MsgBox, Your SLPrice is %SLPrice%. ; so depends on the array number
clipboard := SLPrice
Right?
But note, these testers work easily. The real life example from the OP is copied text and the line 32 contains non-printing characters dealt with by Trim(x) and taking only the first few characters from Left with SubStr(x,1,5).

(HCS12 Microcontroller: Assembly Language) Which branch is appropriate for this loop?

What I'm really stuck on is how I'm supposed to make this loop properly I tried doing every combination for each branch but it either never stops or it stops at the wrong number of loops (supposed to stop after amount of values in RPN_START). I even tried what I did in a previous lab which also failed to work so I'm completely lost as to how I'm supposed to get this program to loop. I understand that the RPN_OUT is the end pointer of the array so I tried putting RPN_START with CPY to compare the values but doing that made it stop after one loop. So I don't know at all which branch I'm supposed to use. Any help/tips/advice would be greatly appreciated. Thank you so much!
ORG DATA
;RPN_IN FCB $06,$03,$2F,$04,$2A,$02,$2B ; 63/4*2+=10
;RPN_IN FCB $05,$01,$02,$2B,$04,$2A,$2B,$03,$2D ; 512+4*+3-
;RPN_IN FCB $02,$03,$2A,$05,$2A,$02,$2F,$01, $2B ; ( ( (2 * 3) * 5) / 2) + 1
RPN_IN FCB $11,$10,$2F,$15,$2A ; ( (11 / 10) ) * 15
RPN_OUT RMB 1
RPN_START FDB RPN_IN ; Pointer to start of RPN array
RPN_END FDB RPN_OUT ; Pointer to end of RPN array
ANSWER RMB 1
TEMP FCB $00
ORG PROG
Entry: ; KEEP THIS LABEL!!
LDS #PROG
LDX #RPN_IN
LOOP:
TFR X,A
LDAA X
...
PSHA
RET:
INX
CPX #RPN_OUT
BNE LOOP
PULA
STAA ANSWER

How to change the qword memory offset in Hopper Assembler v3?

So I got the following (as an example):
0x00000001000022c4 db "Apple", 0
0x0000000100002347 db "Ducks", 0
In a procedure it refers to Apple as such:
lea rcx, qword [ds:0x1000022c4] ; "Apple"
Now I like this string to say Ducks and so I tried to modify assembly instruction by saying:
lea rcx, qword [ds:0x100002347]
However when I apply it says something like:
lea rcx, qword [ds:0x2ace]
Why does it do it?
I was able to fix it by going into the hex editor find the hex value, look how much the offset was off and correct it. But it felt cumbersome.
Hopper Disassembler V3 is great tool to do reverse engineering. I have the same problem too. Here is my solution. My Demo arch is x86_64:
00000001000174a6 mov rsi, qword [ds:0x1004b3040] ; #selector(setAlignment:)
When you see this, it's not mean you could modify the address(0x1004b3040) to whatever you want.
Exactly the assemble code is:
00000001000174a6 movq 0x49bb93(%rip), %rsi ## Objc selector ref: setAlignment:
That means you should convert target address '0x49bb93'
The formula is 0x1004b3040 - 00000001000174a6 - 7 = 0x49bb93
So if you want to modify the address to 100002347 'Ducks', you should follow this formula and find the byte length of your instruction, my is '7'
In my demo I'd like to modify the #selector(setAlignment:) to #selector(setHidden:), So I have to convert it with the formula below:
0x1004b2238 - 0x1000174a6 - 7 = 0x49ad8b
So modify the hex code with 48 8b 35 8b ad 49 00, press 'command + shift + H' to show hex editor in Hopper.
Here comes some demo pictures:
Before my work
After my work
My english is not very good, so welcome to reply.

FindFirstFile and FindNextFile crash my program in assembly. Why?

I am writing a program that looking for files with the extension ".fly". It displays the names of the founded files, but when I try to use FindFirstFile and FindNextFile, my program crashes. I have tried with FindFirstFileA (ANSI Version of the function) , but my code crashes too. Please, give me a example of code if it's possible.
Please, thanks for your answers. Here's my source code written in FASM Assembly
format pe console 4.0
include 'C:\fasm\INCLUDE\WIN32AX.INC'
; Declare a macro to make buffers
macro dup label,lcount
{ forward
label#:
common
repeat lcount
forward
db 0
common
end repeat }
.code
main:
explore_directoy:
invoke FindFirstFile,file_extension, FIND_STRUCT ; find the first *.fly
mov dword [find_handle], eax
find_more_files:
cmp eax, 0
je exit
call show_file
findnextfile:
invoke FindNextFile, dword [find_handle], FIND_STRUCT
jmp find_more_files
show_file:
invoke MessageBox, NULL, addr msg, addr msg_caption, MB_OK ; Easy way of outputing the text
;invoke MessageBox, NULL, addr cFileName, addr msg_caption, MB_OK
ret
exit:
invoke ExitProcess, 0
datazone:
end_msg db 'End of program', 0
msg db 'File founded', 0
msg_caption db 'Assembly program...', 0
file_extension db '*.fly', 0
find_handle dd 0 ; handles/other stuff..
FIND_STRUCT: ; find structure used with searching
dwFileAttributes dd 0
ftCreationTime dd 0,0
ftLastAccessTime dd 0,0
ftLastWriteTime dd 0,0
nFileSizeHigh dd 0
nFileSizeLow dd 0
dwReserved0 dd 0
dwReserved1 dd 0
dup cFileName, 256 ; found file buffer
dup cAlternate, 14
.end main
Your .text section isn't writable. Change
.code
to
section '.text' readable writable executable
Data should go into the .data section, not the .code section. If your assembler supports uninitialized data (all values defined as ?), then it should go into the .data? section (this is the equivalent of a bss (block started by symbol) section used in some other assemblers).

Resources