📄 wdbgexpr.gml
字号:
Division:
The value on the left is divided by the value on the right.
.mnote %
Modulus:
The modulus of the value on the left with respect to the value on the
right is produced.
The result is the remainder when the value on the left is divided by
the value on the right.
.endnote
.*
.keep
.section Unary Arithmetic Operators for the C Grammar
.*
.begnote
.mnote +
Plus:
The result is the value on the right.
.mnote ~_
Minus:
The result is the negation of the value on the right.
.mnote ~~
Bit-wise complement:
The result is the bit-wise complement of the value on the right.
.mnote !
Logical complement:
If the value on the right is equal to 0 then the result is 1;
otherwise it is 0.
.mnote ++
Increment:
Both prefix and postfix operators are supported.
If the object is on the right, it is pre-incremented by 1 (e.g., ++x).
If the object is on the left, it is post-incremented by 1 (e.g., x++).
.mnote ~_ ~_
Decrement:
Both prefix and postfix operators are supported.
If the object is on the right, it is pre-decremented by 1 (e.g., --x).
If the object is on the left, it is post-decremented by 1 (e.g., x--).
.mnote &
Address of:
The result is the address (segment:offset) of the object on the right
(e.g., &main).
.mnote *
Points:
The result is the value stored at the location addressed by the value
on the right (e.g., *(ds:100), *string.loc).
In the absence of typing information, a near pointer is produced.
If the operand does not have a segment specified, the default data segment
(DGROUP) is
assumed.
.code begin
(SS:00FE) = FFFF
var: (SS:0100) = 0152
(SS:0102) = 1240
(SS:0104) = EEEE
.code end
.mnote %
Value at address:
The result is the value stored at the location addressed by the value
on the right (e.g., %(ds:100), %string.loc).
In the absence of typing information, a far pointer is produced.
If the operand does not have a segment specified, the
default data segment (DGROUP) is assumed.
.code begin
(SS:00FE) = FFFF
var: (SS:0100) = 0152
(SS:0102) = 1240
(SS:0104) = EEEE
.code end
.np
Note that this operator is not found in the C or C++ programming
languages.
.endnote
.*
.section Special Unary Operators for the C Grammar
.*
.begnote
.mnote sizeof unary_expression
.exam begin 2
sizeof tyme
sizeof (*tyme)
.exam end
.mnote sizeof(type_name)
.exam begin 1
sizeof( struct tm )
.exam end
.mnote (type_name) unary_expression
The type conversion operator
.sy (type_name)
is used to convert an item from one type to another.
The following describes the syntax of "type_name".
.syntax
type_name ::= type_spec { [ "near" | "far" | "huge" ] "*" }
type_spec ::= typedef_name
| "struct" structure_tag
| "union" union_tag
| "enum" enum_tag
| scalar_type { scalar_type }
scalar_type ::= "char" | "int" | "float" | "double"
| "short" | "long" | "signed" | "unsigned"
.esyntax
.exam begin 2
(float) 4
(int) 3.1415926
.exam end
.mnote [type_name] unary_expression
You can force the debugger to treat a memory reference as a particular
type of value by using a type coercion operator.
A type specification is placed inside brackets as shown above.
.ix 'expressions' 'coercing types'
.ix 'expressions' 'type enforcement'
The basic types are
.kw char
(character, 8 bits),
.kw short
(short integer, 16 bits),
.kw long
(long integer, 32 bits),
.kw float
(single-precision floating-point, 32 bits),
and
.kw double
(double-precision floating-point, 64 bits).
Unless qualified by the
.kw short
or
.kw long
keyword, the
.kw int
type will be 16 bits in 16-bit applications and 32 bits in 32-bit
applications (386, 486 and Pentium systems).
The character, short integer and long integer types may be treated
as
.kw signed
or
.kw unsigned
items.
The default for the character type is unsigned.
The default for the integer types is signed.
.exam begin 12
[char] (default unsigned)
[signed char]
[unsigned char]
[int] (default is signed)
[short] (default is signed)
[short int] (default is signed)
[signed short int]
[long] (default is signed)
[long int] (default is signed)
[signed long]
[unsigned long int]
[float]
[double]
.exam end
.pc
Note that it is unnecessary to specify the
.kw int
keyword when
.kw short
or
.kw long
are specified.
.mnote ?
Existence test:
The "?" unary operator may be used to test for the existence of
a symbol.
.exam begin 1
?id
.exam end
.pc
The result of this expression is 1 if "id" is a symbol known to
the debugger and 0 otherwise.
If the symbol does not exist in the current scope then it must
be qualified with its module name.
Automatic symbols exist only in the current function.
.endnote
.*
.section Binary Address Operator for the C Grammar
.*
.begnote
.mnote :
Memory locations can be referenced by using the binary ":" operator
and a combination of constants, register names, and symbol names.
In the Intel 80x86 architecture, a memory reference requires a segment
and offset specification.
A memory reference using the ":" operator takes the following form:
.syntax
segment:offset
.esyntax
.pc
The elements
.sy segment
and
.sy offset
can be expressions.
.exam begin 2
(ES):(DI+100)
(SS):(SP-20)
.exam end
.endnote
.*
.section Primary Expression Operators for the C Grammar
.*
.begnote
.mnote []
Elements of an array can be identified using subscript expressions.
Consider the following 3-dimensional array defined in the "C"
language.
.exam begin 10
char *ProcessorType[2][4][2] =
{ { { "Intel 8086", "Intel 8088" },
{ "Intel 80186", "Intel 80188" },
{ "Intel 80286", "unknown" },
{ "Intel 80386", "unknown" } },
{ { "NEC V30", "NEC V20" },
{ "unknown", "unknown" },
{ "unknown", "unknown" },
{ "unknown", "unknown" } } };
.exam end
.pc
This array can be viewed as two layers of rectangular matrices of 4
rows by 2 columns.
The array elements are all pointers to string values.
.np
By using a subscript expression, specific slices of an array can be
displayed.
To see only the values of the first layer, the following expression can
be issued.
.exam begin 1
processortype[0]
.exam end
.np
To see only the first row of the first layer, the following expression
can be issued.
.exam begin 1
processortype[0][0]
.exam end
.pc
To see the second row of the first layer, the following command can be
issued.
.exam begin 1
processortype[0][1]
.exam end
.np
To see the value of a specific entry in a matrix, all the indices can
be specified.
.exam begin 3
processortype[0][0][0]
processortype[0][0][1]
processortype[0][1][0]
.exam end
.mnote ()
The function call operators appear to the right of a symbol name and
identify a function call in an expression.
The parentheses can contain arguments.
.exam begin 3
ClearScreen()
PosCursor( 10, 20 )
Line( 15, 1, 30, '-', '+', '-' )
.exam end
.mnote .
The "." operator indicates field selection in a structure.
In the following example,
.id tyme2
is a structure and
.id tm_year
is a field in the structure.
.exam begin 1
tyme2.tm_year
.exam end
.mnote ->
The "->" operator indicates field selection when using a pointer
to a structure.
In the following example,
.id tyme
is the pointer and
.id tm_year
is a field in the structure to which it points.
.exam begin 1
tyme->tm_year
.exam end
.endnote
.endlevel
.*
.section Operators for the C++ Grammar
.*
.np
.ix 'expressions' 'C++ operators'
Debugger support for the C++ grammar includes all of the C operators
described in the previous section entitled :HDREF refid='videxpc'..
In addition to this, the debugger supports a variety of C++ operators
which are described in the
.us C++ Programming Language
manual.
.np
Perhaps the best way to illustrate the additional capabilities of
the debugger's support for the C++ grammar is by way of an example.
The following C++ program encompasses the features of C++ that we will
use in our debugging example.
.exam begin
// DBG_EXAM.C: C++ debugging example program
struct BASE {
int a;
BASE() : a(0) {}
~~BASE(){}
BASE & operator =( BASE const &s )
{
a = s.a;
return *this;
}
virtual void foo()
{
a = 1;
}
};
.exam break
struct DERIVED : BASE {
int b;
DERIVED() : b(0) {}
~~DERIVED() {}
DERIVED & operator =( DERIVED const &s )
{
a = s.a;
b = s.b;
return *this;
}
virtual void foo()
{
a = 2;
b = 3;
}
virtual void foo( int )
{
}
};
.exam break
void use( BASE *p )
{
p->foo();
}
.exam break
void main()
{
DERIVED x;
DERIVED y;
use( &x );
y = x;
}
.exam end
.np
Compile and link this program so that the most comprehensive debugging
information is included in the executable file.
.*
.beglevel
.*
.section Ambiguity Resolution in the C++ Grammar
.*
.np
Continuing with the example of the previous section, we can step into
the call to
.id use
and up to the
.id p->foo()
function call. Try to set a breakpoint at foo.
.np
You will be presented with a window containing a list of "foo"
functions to choose from since the reference to
.id foo
at this point is ambiguous.
Select the one in which you are interested.
.np
You may also have observed that, in this instance,
.id p
is really a pointer to the variable
.id x
which is a
.id DERIVED
type.
To display all the fields of
.id x,
you can type cast it as follows.
.exam begin 1
*(DERIVED *)p
.exam end
.*
.section The "this" Operator for the C++ Grammar
.*
.np
Continuing with the example of the previous sections, we can step into
the call to
.id f->foo()
and up to the
.id b=3&semi.
statement.
You can use the "this" operator as illustrated in the following
example.
.exam begin 2
this->a
*this
.exam end
.*
.section "operator" Functions in the C++ Grammar
.*
.np
Continuing with the example of the previous sections, we can set
breakpoints at C++ operators using expressions similar to the
following:
.exam begin 1
operator =
.exam end
.millust begin
DERIVED & operator =( DERIVED const &s )
{
a = s.a;
b = s.b;
return *this;
}
.millust end
.*
.section Scope Operator "::" for the C++ Grammar
.*
.np
We can use the scope operator "::" to identify what it is that we wish
to examine.
Continuing with the example of the previous sections, we can enter an
address like:
.millust begin
base::foo
.millust end
.np
In some cases, this also helps to resolve any ambiguity.
The example above permits us to set a breakpoint at the source code for the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -