news 2026/5/1 4:56:13

ACPI!PnpiBiosAddressDoubleToIoDescriptor函数分析用了2个描述符rangeDescriptor和privateDescriptor

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ACPI!PnpiBiosAddressDoubleToIoDescriptor函数分析用了2个描述符rangeDescriptor和privateDescriptor

ACPI!PnpiBiosAddressDoubleToIoDescriptor函数分析用了2个描述符rangeDescriptor和privateDescriptor

//
// Handle the hints that are given to us
//
if (buffer->GFlag & PNP_ADDRESS_FLAG_MINIMUM_FIXED &&
buffer->GFlag & PNP_ADDRESS_FLAG_MAXIMUM_FIXED) {

if (Descriptor->Type == CmResourceTypeBusNumber) {

oldValue = Descriptor->u.BusNumber.Length;
newValue = Descriptor->u.BusNumber.Length =
Descriptor->u.BusNumber.MaxBusNumber -
Descriptor->u.BusNumber.MinBusNumber + 1;

}


//
// Move to the next descriptor
//
buffer += increment;
tagName = *buffer;

}

switch(tagName) {

case TAG_DOUBLE_ADDRESS: {

status = PnpiBiosAddressDoubleToIoDescriptor(
buffer,
Array,
ArrayIndex,
Flags
);

ACPIPrint( (
ACPI_PRINT_RESOURCES_2,
"PnpBiosResourcesToNtResources: TAG_DOUBLE_ADDRESS = 0x%8lx\n",
status
) );
break;
}

0: kd> kc
#
00 ACPI!PnpiBiosAddressDoubleToIoDescriptor
01 ACPI!PnpBiosResourcesToNtResources
02 ACPI!ACPIBusIrpQueryResourceRequirements
03 ACPI!ACPIDispatchIrp
04 nt!IofCallDriver
05 nt!IopSynchronousCall
06 nt!PpIrpQueryResourceRequirements
07 nt!PiQueryResourceRequirements
08 nt!PiProcessNewDeviceNode
09 nt!PipProcessDevNodeTree
0a nt!PipDeviceActionWorker
0b nt!PipRequestDeviceAction
0c nt!IopInitializeBootDrivers
0d nt!IoInitSystem
0e nt!Phase1Initialization
0f nt!PspSystemThreadStartup
10 nt!KiThreadStartup
0: kd> dv
Data = 0xe129e381 "???"
Array = 0xe1278800
ArrayIndex = 0
Flags = 1


0: kd> db 0xe129e381
e129e381 87 18 00 00 0c 03 00 00-00 00 00 00 0a 00 ff ff ................
e129e391 0b 00 00 00 00 00 00 00-02 00 00 87 18 00 00 0c ................


0: kd> dt PNP_DWORD_ADDRESS_DESCRIPTOR 0xe129e381
ACPI!PNP_DWORD_ADDRESS_DESCRIPTOR
+0x000 Tag : 0x87 ''
+0x001 Length : 0x18
+0x003 RFlag : 0 '' PNP_ADDRESS_MEMORY_TYPE 0x0
+0x004 GFlag : 0xc ''
+0x005 TFlag : 0x3 ''
+0x006 Granularity : 0
+0x00a MinimumAddress : 0xa0000
+0x00e MaximumAddress : 0xbffff
+0x012 TranslationAddress : 0
+0x016 AddressLength : 0x20000


DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, // Granularity
0x000A0000, // Range Minimum
0x000BFFFF, // Range Maximum
0x00000000, // Translation Offset
0x00020000, // Length
0x00,, , AddressRangeMemory, TypeStatic)


//
// These are the possible values for RFlag Means
//
#define PNP_ADDRESS_MEMORY_TYPE 0x0
#define PNP_ADDRESS_IO_TYPE 0x1
#define PNP_ADDRESS_BUS_NUMBER_TYPE 0x2

//
// The Global flags
//
#define PNP_ADDRESS_FLAG_CONSUMED_ONLY 0x1
#define PNP_ADDRESS_FLAG_SUBTRACTIVE_DECODE 0x2
#define PNP_ADDRESS_FLAG_MINIMUM_FIXED 0x4
#define PNP_ADDRESS_FLAG_MAXIMUM_FIXED 0x8

//
// Ensure that there is enough space within the chosen list to add the
// resource
//
status = PnpiUpdateResourceList( & (Array[ArrayIndex]), &rangeDescriptor );
if (!NT_SUCCESS(status)) {

return status;
}


0: kd> t
eax=f789a164 ebx=80ae2bca ecx=80ae0dfa edx=80b18958 esi=e1278800 edi=e129e381
eip=f744a2d2 esp=f789a138 ebp=f789a158 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000206
ACPI!PnpiUpdateResourceList:
f744a2d2 55 push ebp
0: kd> dv
ResourceList = 0xe1278800
ResourceDesc = 0xf789a164
0: kd> dx -r1 ((ACPI!_IO_RESOURCE_LIST * *)0xe1278800)
((ACPI!_IO_RESOURCE_LIST * *)0xe1278800) : 0xe1278800 [Type: _IO_RESOURCE_LIST * *]
0xe12a7908 [Type: _IO_RESOURCE_LIST *]


//
// Find the next descriptor to use
//
*ResourceDesc = & ( (*ResourceList)->Descriptors[ (*ResourceList)->Count ] );

0: kd> dv ResourceDesc
ResourceDesc = 0xf789a164
0: kd> dx -r1 ((ACPI!_IO_RESOURCE_DESCRIPTOR * *)0xf789a164)
((ACPI!_IO_RESOURCE_DESCRIPTOR * *)0xf789a164) : 0xf789a164 [Type: _IO_RESOURCE_DESCRIPTOR * *]
0xe12a7930 : No Resource [Type: _IO_RESOURCE_DESCRIPTOR *]

0: kd> dt ACPI!_IO_RESOURCE_LIST 0xe12a7908
+0x000 Version : 1
+0x002 Revision : 1
+0x004 Count : 1
+0x008 Descriptors : [1] _IO_RESOURCE_DESCRIPTOR


0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910
+0x000 Option : 0 ''
+0x001 Type : 0x6 ''
+0x002 ShareDisposition : 0x3 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR -v
struct _IO_RESOURCE_DESCRIPTOR, 7 elements, 0x20 bytes
+0x000 Option : UChar
+0x001 Type : UChar
+0x002 ShareDisposition : UChar
+0x003 Spare1 : UChar
+0x004 Flags : Uint2B
+0x006 Spare2 : Uint2B
+0x008 u : union __unnamed, 8 elements, 0x18 bytes
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*2
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*3
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*4
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*5
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*6
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*7
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*8
+0x000 Option : 0x22 '"'
+0x001 Type : 0x8 ''
+0x002 ShareDisposition : 0x2c ','
+0x003 Spare1 : 0x4 ''
+0x004 Flags : 0x624f
+0x006 Spare2 : 0x7153
+0x008 u : __unnamed

//
// Update the count of in-use descriptors
//
(*ResourceList)->Count += 1;


0: kd> dt ACPI!_IO_RESOURCE_LIST 0xe12a7908
+0x000 Version : 1
+0x002 Revision : 1
+0x004 Count : 2
+0x008 Descriptors : [1] _IO_RESOURCE_DESCRIPTOR


//
// Ensure that there is enough space within the chosen list to add the
// resource
//
status = PnpiUpdateResourceList( & (Array[ArrayIndex]), &rangeDescriptor );
if (!NT_SUCCESS(status)) {

return status;
}

0: kd> dv rangeDescriptor
rangeDescriptor = 0xe12a7930 No Resource


//
// If this is I/O or Memory, then we will need to make enough space for
// a device private resource too.
//
if ((buffer->RFlag == PNP_ADDRESS_MEMORY_TYPE) ||
(buffer->RFlag == PNP_ADDRESS_IO_TYPE)) {

status = PnpiUpdateResourceList( & (Array[ArrayIndex]), &privateDescriptor );

if (!NT_SUCCESS(status)) {
return status;
}


0: kd> kc
#
00 ACPI!PnpiUpdateResourceList
01 ACPI!PnpiBiosAddressDoubleToIoDescriptor
02 ACPI!PnpBiosResourcesToNtResources
03 ACPI!ACPIBusIrpQueryResourceRequirements
04 ACPI!ACPIDispatchIrp
05 nt!IofCallDriver
06 nt!IopSynchronousCall
07 nt!PpIrpQueryResourceRequirements
08 nt!PiQueryResourceRequirements
09 nt!PiProcessNewDeviceNode
0a nt!PipProcessDevNodeTree
0b nt!PipDeviceActionWorker
0c nt!PipRequestDeviceAction
0d nt!IopInitializeBootDrivers
0e nt!IoInitSystem
0f nt!Phase1Initialization
10 nt!PspSystemThreadStartup
11 nt!KiThreadStartup
0: kd> dv
ResourceList = 0xe1278800
ResourceDesc = 0xf789a160
0: kd> dx -r1 ((ACPI!_IO_RESOURCE_LIST * *)0xe1278800)
((ACPI!_IO_RESOURCE_LIST * *)0xe1278800) : 0xe1278800 [Type: _IO_RESOURCE_LIST * *]
0xe12a7908 [Type: _IO_RESOURCE_LIST *]


0: kd> gu
eax=00000000 ebx=80ae2bca ecx=f789a160 edx=80b18958 esi=e1278800 edi=e129e381
eip=f744ac0c esp=f789a144 ebp=f789a158 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000206
ACPI!PnpiBiosAddressDoubleToIoDescriptor+0xa8:
f744ac0c 85c0 test eax,eax
0: kd> dt ACPI!_IO_RESOURCE_LIST 0xe12a7908
+0x000 Version : 1
+0x002 Revision : 1
+0x004 Count : 3
+0x008 Descriptors : [1] _IO_RESOURCE_DESCRIPTOR


0: kd> dv privateDescriptor
privateDescriptor = 0xe12a7950 No Resource
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed

privateDescriptor->Type = CmResourceTypeDevicePrivate;

0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed


#define CmResourceTypeNonArbitrated 128 // Not arbitrated if 0x80 bit set
#define CmResourceTypeConfigData 128 // ResType_Reserved (0x8000)
#define CmResourceTypeDevicePrivate 129 // ResType_DevicePrivate (0x8001)
#define CmResourceTypePcCardConfig 130 // ResType_PcCardConfig (0x8002)
#define CmResourceTypeMfCardConfig 131 // ResType_MfCardConfig (0x8003)


privateDescriptor->Flags = TRANSLATION_DATA_PARENT_ADDRESS;

0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed


#define TRANSLATION_RANGE_SPARSE 0x0001
#define TRANSLATION_DATA_PARENT_ADDRESS 0x6000


//
// Fill in the top 32 bits of the start address.
//
privateDescriptor->u.DevicePrivate.Data[2] = 0;

0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950 -r
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed
+0x000 Port : __unnamed
+0x000 Length : 0
+0x004 Alignment : 0
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Memory : __unnamed
+0x000 Length : 0
+0x004 Alignment : 0
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Interrupt : __unnamed
+0x000 MinimumVector : 0
+0x004 MaximumVector : 0
+0x000 Dma : __unnamed
+0x000 MinimumChannel : 0
+0x004 MaximumChannel : 0
+0x000 Generic : __unnamed
+0x000 Length : 0
+0x004 Alignment : 0
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 DevicePrivate : __unnamed
+0x000 Data : [3] 0
+0x000 BusNumber : __unnamed
+0x000 Length : 0
+0x004 MinBusNumber : 0
+0x008 MaxBusNumber : 0
+0x00c Reserved : 0
+0x000 ConfigData : __unnamed
+0x000 Priority : 0
+0x004 Reserved1 : 0
+0x008 Reserved2 : 0


length = buffer->AddressLength;
alignment = buffer->Granularity + 1;

//
// Calculate the bounds of both the parent and child sides of
// the bridge.
//
// The translation field applies to the parent address i.e.
// the child address is the address in the buffer and the
// parent address is the addition of the child address and
// the translation field.
//

parentMin = buffer->MinimumAddress + buffer->TranslationAddress;
childMin = buffer->MinimumAddress;
childMax = buffer->MaximumAddress;


switch (buffer->RFlag) {
case PNP_ADDRESS_MEMORY_TYPE:

//
// Set the proper ranges
//

rangeDescriptor->u.Memory.Alignment = alignment;
rangeDescriptor->u.Memory.Length = length;
rangeDescriptor->u.Memory.MinimumAddress.LowPart = childMin;
rangeDescriptor->u.Memory.MaximumAddress.LowPart = childMax;
rangeDescriptor->u.Memory.MinimumAddress.HighPart =
rangeDescriptor->u.Memory.MaximumAddress.HighPart = 0;
rangeDescriptor->Type = CmResourceTypeMemory;

typedef enum _CM_RESOURCE_TYPE {
CmResourceTypeNull = 0, // Reserved
CmResourceTypePort, 1
CmResourceTypeInterrupt, 2
CmResourceTypeMemory, 3
CmResourceTypeDma, 4
CmResourceTypeDeviceSpecific
} CM_RESOURCE_TYPE;


0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20 -r
+0x000 Option : 0 ''
+0x001 Type : 0x3 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
+0x000 Port : __unnamed
+0x000 Length : 0x20000
+0x004 Alignment : 1
+0x008 MinimumAddress : _LARGE_INTEGER 0xa0000
+0x010 MaximumAddress : _LARGE_INTEGER 0xbffff
+0x000 Memory : __unnamed
+0x000 Length : 0x20000
+0x004 Alignment : 1
+0x008 MinimumAddress : _LARGE_INTEGER 0xa0000
+0x010 MaximumAddress : _LARGE_INTEGER 0xbffff
+0x000 Interrupt : __unnamed
+0x000 MinimumVector : 0x20000
+0x004 MaximumVector : 1
+0x000 Dma : __unnamed
+0x000 MinimumChannel : 0x20000
+0x004 MaximumChannel : 1
+0x000 Generic : __unnamed
+0x000 Length : 0x20000
+0x004 Alignment : 1
+0x008 MinimumAddress : _LARGE_INTEGER 0xa0000
+0x010 MaximumAddress : _LARGE_INTEGER 0xbffff
+0x000 DevicePrivate : __unnamed
+0x000 Data : [3] 0x20000
+0x000 BusNumber : __unnamed
+0x000 Length : 0x20000
+0x004 MinBusNumber : 1
+0x008 MaxBusNumber : 0xa0000
+0x00c Reserved : 0
+0x000 ConfigData : __unnamed
+0x000 Priority : 0x20000
+0x004 Reserved1 : 1
+0x008 Reserved2 : 0xa0000

if (buffer->TFlag & TRANSLATION_MEM_TO_IO) {

//
// The device private describes the parent. With this
// flag set, the descriptor type of the parent will
// changed from Memory to IO.
//

privateDescriptor->u.DevicePrivate.Data[0] =
CmResourceTypePort;

} else {

//
// The parent descriptor type will not change.
//

privateDescriptor->u.DevicePrivate.Data[0] =
CmResourceTypeMemory;

}
0: kd> dd 0xe12a7910+20*2
e12a7950 00008100 00006000 00000003 000a0000
e12a7960 00000000 00000000 00000000 00000000


0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*2 -r
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed
+0x000 Port : __unnamed
+0x000 Length : 3
+0x004 Alignment : 0xa0000
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Memory : __unnamed
+0x000 Length : 3
+0x004 Alignment : 0xa0000
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Interrupt : __unnamed
+0x000 MinimumVector : 3
+0x004 MaximumVector : 0xa0000
+0x000 Dma : __unnamed
+0x000 MinimumChannel : 3
+0x004 MaximumChannel : 0xa0000
+0x000 Generic : __unnamed
+0x000 Length : 3
+0x004 Alignment : 0xa0000
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 DevicePrivate : __unnamed
+0x000 Data : [3] 3
+0x000 BusNumber : __unnamed
+0x000 Length : 3
+0x004 MinBusNumber : 0xa0000
+0x008 MaxBusNumber : 0
+0x00c Reserved : 0
+0x000 ConfigData : __unnamed
+0x000 Priority : 3
+0x004 Reserved1 : 0xa0000
+0x008 Reserved2 : 0
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!unsigned long (*)[3])0xe12a7958))
(*((ACPI!unsigned long (*)[3])0xe12a7958)) [Type: unsigned long [3]]
[0] : 0x3 [Type: unsigned long]
[1] : 0xa0000 [Type: unsigned long]
[2] : 0x0 [Type: unsigned long]


回顾:parentMin
parentMin = buffer->MinimumAddress + buffer->TranslationAddress;
childMin = buffer->MinimumAddress;
childMax = buffer->MaximumAddress;
回顾结束:

//
// Handle global flags
//
PnpiBiosAddressHandleGlobalFlags( buffer, rangeDescriptor );
return STATUS_SUCCESS;
}

VOID
PnpiBiosAddressHandleGlobalFlags(
IN PVOID Buffer,
IN PIO_RESOURCE_DESCRIPTOR Descriptor
)
{
} else {

Descriptor->ShareDisposition = CmResourceShareShared;

}

0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20
+0x000 Option : 0 ''
+0x001 Type : 0x3 ''
+0x002 ShareDisposition : 0x3 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x20
+0x006 Spare2 : 0
+0x008 u : __unnamed

0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*2
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!unsigned long (*)[3])0xe12a7958))
(*((ACPI!unsigned long (*)[3])0xe12a7958)) [Type: unsigned long [3]]
[0] : 0x3 [Type: unsigned long]
[1] : 0xa0000 [Type: unsigned long]
[2] : 0x0 [Type: unsigned long]

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 18:41:00

2.1 链式法则

1.链式法则简介 2.链式法则应用1.链式法则简介 1).法则前提a.函数u g(x)在x处可导b.函数y f(x)在u g(x)处可导则复合函数y f(g(x))在x处可导, 且导数满足链式法则2).两种核心表达形式a.微分形式2).函数复合形式2.链式法则应用 a.求y tan(3 * x^2 - 1)的导数b.f(x) tan((x…

作者头像 李华
网站建设 2026/5/1 1:10:35

第4项适应症获批!默沙东押注的这款中国“王炸”再破圈

一次成功或许源于运气,但接二连三的高效突围,必然代表着底层商业逻辑的正确、与创新战略的胜利!今日,科伦博泰芦康沙妥珠单抗(sac-TMT)再传捷报——成功获批至少经一线化疗治疗的HR/HER2-晚期乳腺癌&#x…

作者头像 李华
网站建设 2026/4/29 6:40:43

建议收藏|千笔写作工具,最受喜爱的AI论文软件

你是否正在为论文写作而焦虑?选题无从下手,框架难以搭建,文献查找耗时费力,查重率总不达标,格式修改反复出错……这些困扰是否让你感到力不从心?别让论文成为你大学生活的“拦路虎”,千笔AI&…

作者头像 李华