Comparing strings in 8086 real mode
use AX for comparing, it’s changed anyways; there’s no need to clobber anything else; and let the CPU do the “pointer calculation”, you can read from [BX 2], there’s no need to change it
mov bx, REBOOT_CMD
call is_cmd
or ax, ax
jz reboot_cmd
is_cmd:
mov ax, [bx]
cmp ax, [BUFFER] ; [buffer] with [bx]
jne is_cmd_no
mov ax, [bx 2]
cmp ax, [BUFFER 2] ; [buffer 2] with [bx 2]
jne is_cmd_no
mov ax, 1 ; is_cmd_yes
ret
is_cmd_no:
xor ax, ax
ret
or even better, inline it into the use-case
is_reboot:
mov ax, [REBOOT_CMD]
cmp ax, [BUFFER] ; [buffer] with "rs"
jne no_reboot
mov ax, [REBOOT_CMD 2]
cmp ax, [BUFFER 2] ; [buffer 2] with "et"
jz reboot_cmd
no_reboot:
note: the 2 branches differ, first is a “jne”, second a “jz” to the reboot case. it’s like an “AND” in C, where the 2nd part of the expression is only evaluated, if the first had TRUE as result
if you feel like obfuscting if, even the “BUFFER db “rset”,0″ is obsolete, you could compare [BUFFER] with “rs” ( which is “s” 0x100 * “r” = 0x7372 ) and [BUFFER 2] with “et” ( = “e” 0x100 * “t” = 0x7465 ):
is_reboot:
cmp word ptr [BUFFER],0x7372 ; [buffer] with "rs"
jne no_reboot
cmp word ptr [BUFFER 2],0x7465 ; [buffer 2] with "et"
jz reboot_cmd
no_reboot:
How to search string for slashes or colon on windows command line or in batch file?
The commands SET and IF can be used to check if a string assigned to an environment variable contains a specific character or string.
Example:
@echo off
setlocal EnableExtensions
for %%I in ("C:UsersMikeW" "FolderFileName" "Folder or file name") do call :ColonBackslash %%I
endlocal
goto :EOF
:ColonBackslash
set "Argument=%~1"
rem Substitute in argument string all colons by nothing and compare this
rem string with unmodified argument string. The argument string contains
rem a colon if the modified and the unmodified strings are not equal.
if not "%Argument::=%" == "%Argument%" (
echo Colon in argument: %Argument%
goto :EOF
)
rem Substitute in argument string all backslashes by nothing and compare
rem this string with unmodified argument string. The argument string
rem contains a backslash if the modified and the unmodified strings
rem are not equal.
if not "%Argument:=%" == "%Argument%" (
echo Backslash in argument: %Argument%
goto :EOF
)
echo No colon or backslash in: %Argument%
goto :EOF
This batch file outputs:
Colon in argument: C:UsersMikeW
Backslash in argument: FolderFileName
No colon or backslash in: Folder or file name
Comparing strings with substituted characters/strings with unmodified string can be used to determine type of input string as demonstrated with the batch code below:
@echo off
setlocal EnableExtensions
for %%I in ("C:UsersMikeW" "C:UsersMi:keW" "documentation" "\serversharefolder" "\serversharefolder1..folder2" "\serversharefo:lder" "\server" "\serversharefolder.." "%SystemRoot%.." ".Folder" "....Folder" "Windows" ">:Invalid") do call :classifyInput %%I
endlocal
goto :EOF
:classifyInput
rem Subroutine called with no parameter or with just "" as parameter.
if "%~1" == "" goto :EOF
set "Argument=%~1"
rem Replace all forward slashes by backslashes in argument string.
set "Argument=%Argument:/=%"
rem Is the second character a colon and third character a backlash?
if "%Argument:~1,2%" == ":" goto AbsolutePath
rem Is there a colon anywhere else than at second position in argument?
rem C:Folder is interpreted as invalid argument and not as relative
rem path to subfolder "Folder" of current directory on drive C:.
if not "%Argument::=%" == "%Argument%" (
echo Invalid argument: %1
goto :EOF
)
rem Starts the argument with two backslashes?
if "%Argument:~0,2%" == "\" goto PathUNC
rem Starts the argument with for a path relative to current drive?
if "%Argument:~0,1%" == "" (
echo Relative path: %1
goto :EOF
)
rem Starts the argument with . for a path relative to current directory?
if "%Argument:~0,2%" == "." (
echo Relative path: %1
goto :EOF
)
rem Starts the argument with .. for a path relative to parent directory?
if "%Argument:~0,3%" == ".." (
echo Relative path: %1
goto :EOF
)
rem Contains the argument a backslash for a path relative to current directory?
if not "%Argument:=%" == "%Argument%" (
echo Relative path: %1
goto :EOF
)
echo Name without path: %1
goto :EOF
:AbsolutePath
set "Remaining=%Argument:~2%"
rem Is there a colon anywhere else after second position in argument?
if not "%Remaining::=%" == "%Remaining%" (
echo Invalid argument: %1
goto :EOF
)
rem Is the first character a drive letter if second character is a colon?
set "FirstIsLetter="
for /F "delims=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" %%# in ("%Argument:~0,1%") do set "FirstIsLetter=%%#"
if not "%FirstIsLetter%" == "" (
echo Invalid argument: %1
goto :EOF
)
rem Contains the absolute path also . or .. in path?
if "%Argument:.=%" == "%Argument%" (
echo Absolute path: %1
) else (
echo Abs. rel. path: %1
)
goto :EOF
:PathUNC
rem Does the UNC path contain also a colon?
if not "%Argument::=%" == "%Argument%" (
echo Invalid argument: %1
goto :EOF
)
set "ServerName="
set "ShareName="
set "Remaining="
for /F "tokens=1,2* delims=" %%A in ("%Argument%") do (
set "ServerName=%%A"
set "ShareName=%%B
set "Remaining=%%C"
)
rem Is there no share name specified after server name in UNC path?
if "%ShareName%" == "" (
echo Invalid argument: %1
goto :EOF
)
rem Is there an invalid share name specified after server name in UNC path?
if "%ShareName%" == "." (
echo Invalid argument: %1
goto :EOF
)
rem Is there an invalid share name specified after server name in UNC path?
if "%ShareName%" == ".." (
echo Invalid argument: %1
goto :EOF
)
rem Contains the UNC path also . or .. in remaining path?
if "%Remaining:.=%" == "%Remaining%" (
echo UNC path: %1
) else (
echo UNC rel. path: %1
)
goto :EOF
The output is:
Absolute path: "C:UsersMikeW"
Invalid argument: "C:UsersMi:keW"
Name without path: "documentation"
UNC path: "\serversharefolder"
UNC rel. path: "\serversharefolder1..folder2"
Invalid argument: "\serversharefo:lder"
Invalid argument: "\server"
UNC rel. path: "\serversharefolder.."
Abs. rel. path: "C:WINDOWS.."
Relative path: ".Folder"
Relative path: "....Folder"
Relative path: "Windows"
Invalid argument: ">:Invalid"
But this batch code is not complete for checking for invalid paths, folder or file names in an argument string. There are still a lot of possible errors not detected by this batch code.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
It would be better to let Windows kernel check if the argument specifies an existing folder or file independent if the argument string is without or with a path of any type and being valid at all. See the topics:
And in case of testing for validity on non existing folder/file, just create the file/folder, suppress the error message using 2>nul
(see the Microsoft article Using command redirection operators) and check with if errorlevel 1
or with if exist "%~1"
if the folder/file could be created successfully, or if this operation failed because of an invalid folder/file name string, denied access, missing permissions, etc.
Online compiler(online gdb)works correctly while g and gcc on windows 10 cmd doesn’t work when comparing strings
When I compare 2 strings in the website “online gdb”, if the comparison is equal it gives 10, if it’s not it doesn’t give 10(It’s already weird that it gives 10 instead of 0, but it works so I didn’t care). But since I tried to compile my code with g or gcc(I tried with -g too for both)it gives -1 or 1, or only 1, but never 0. Thanks to everyone which will read this code and will help me.
#include <stdio.h>
#include <math.h>
#include <string.h>
int main()
{
char v1q[55], v2q[55], v3q[55], v4q[55];
float v1, v2, v3, v4, vr, min, max;
int comparison;
int v3b = 1;
printf("Per la prima banda non esiste l'oro e l'argento;nPer la seconda banda non esiste l'oro e l'argento;nPer la terza banda non esiste il bianco;nPer la quarta banda esistono SOLO il bianco, oro e argento.nn");
printf("Prima cifra: ");
fgets(v1q, sizeof(v1q), stdin);
if(strcmp(v1q, "nero") == 0)
{
printf("nNon esiste un valore per il nero, per la prima banda");
}
if(strcmp(v1q, "marrone") == 0)
{
v1 = 10;
}
if(strcmp(v1q, "rosso") == 0)
{
v1 = 20;
}
if(strcmp(v1q, "arancione") == 0)
{
v1 = 30;
}
if(strcmp(v1q, "giallo") == 0)
{
v1 = 40;
}
if(strcmp(v1q, "verde") == 0)
{
v1 = 50;
}
if(strcmp(v1q, "blu") == 0)
{
v1 = 60;
}
if(strcmp(v1q, "viola") == 0)
{
v1 = 70;
}
if(strcmp(v1q, "grigio") == 0)
{
v1 = 80;
}
if(strcmp(v1q, "bianco") == 0)
{
v1 = 90;
}
if(strcmp(v1q, "oro") == 0)
{
printf("nNon esiste un valore per l'oro, per la prima banda");
}
if(strcmp(v1q, "argento") == 0)
{
printf("nNon esiste un valore per l'argento, per la prima banda");
}
comparison = strcmp(v1q, "marrone");
printf("%d", comparison);
}
Why does call set work differently in a cmd windows versus a .cmd file?
I am trying to use the Windows CMD SET
string manipulation versions in a programmatic way. The two versions of SET
are …
SET New_String=%String:Old_Text=New_Text%
In variable String
replace Old_Text
with New_Text
, and return result in variable New_String
.
SET New_String=%String:~Number_Of_Chars_To_Skip,Number_Of_Chars_To_Keep%
In variable String
extract Number_Of_Chars_To_Keep
after skipping Number_Of_Chars_To_Skip
, and return result in variable New_String
Old_Text, New_Text, Number_Of_Chars_To_Skip, Number_Of_Chars_To_Keep
must all be literals, not variables. So, typical usage would be like this …
SET New_String=%String:abcd=fghi%
SET New_String=%String:~2,4%
Usage like this won’t work …
SET New_String=%String:%Old_Text%=%New_Text%%
SET New_String=%String:~%Skip_Count%,%Keep_Count%%
To do the above two SET
s you have to CALL SET
, like …
CALL SET New_String=%%String:%Old_Text%=%New_Text%%%
CALL SET New_String=%%String:~%Skip_Count%,%Keep_Count%%%
So, I have this following test code fragment …
SET "Chars=" & SET "String=0123456789" & SET "Skip=1" & SET "Keep=3"
CALL SET Chars=%%String:~%Skip%,%Keep%%%
ECHO Chars="%Chars%" (expected to be "123")
From a CMD file this works correctly. The CALL
has been expanded to SET Chars=%string:~1,3%
and has returned the expected result 123. But, and a big but it is, from a CMD Window (with the same variables) the exact same CALL SET
returns this …
23456789Skip%,3%%
Why doesn’t this work in a CMD Window? I researched around and haven’t found any info explaining why.
Windows command prompt: how to pass multi-line string parameters
I have a program that accepts a string parameter. I create a batch file that executes the program and a multiline string paramter. I also have a second parameter after the multiline string.
C:>MyProgram "This is a
multiline text" parameter2
When I run this, only the first line of string is included in the command and the subsequent lines and the second parameter are ignored. Is there any way to pass multiline string parameters?